typescript_权威TypeScript手册

typescript

TypeScript is the one of the tools people want to learn most, according to a Stack Overflow Survey of 90,000 developers.

根据对90,000名开发人员的Stack Overflow调查 ,TypeScript是人们最想学习的工具之一。

TypeScript has exploded in popularity, community size, and adoption over the past few years. Today, even Facebook's Jest project from Facebook is moving to TypeScript.

在过去的几年中,TypeScript的受欢迎程度,社区规模和采用率都呈爆炸式增长。 今天,即使Facebook的Facebook Jest项目也正在迁移到TypeScript

什么是TypeScript? (What Is TypeScript?)

TypeScript is a statically-typed superset of JavaScript which aims to ease the development of large javascript applications. It is also knows as JavaScript that scales.

TypeScript是JavaScript的静态类型超集,旨在简化大型javascript应用程序的开发。 它也称为可扩展JavaScript

为什么要使用TypeScript? (Why use TypeScript?)

JavaScript has evolved a lot over the past few years. It is the most versatile cross-platform language used for both client and server side.

在过去的几年中,JavaScript发展了很多。 它是用于客户端和服务器端的最通用的跨平台语言。

But JavaScript was never meant for such large-scale application development. It is a dynamic language with no type system, meaning that a variable can have any type of value, such as a string or boolean.

但是,JavaScript从来都不适合进行如此大规模的应用程序开发。 这是一种没有类型系统的动态语言,这意味着变量可以具有任何类型的值,例如字符串或布尔值。

Type systems increase code quality, readability and make it easier to maintain and refactor codebase. More importantly, errors can be caught at compile time rather than at run time.

类型系统提高了代码质量,可读性,并使维护和重构代码库变得更加容易。 更重要的是,错误可以在编译时而不是在运行时捕获。

Without a type system, it's difficult to scale JavaScript to build complex applications with large teams working on the same code.

如果没有类型系统,则很难扩展JavaScript以使大型团队使用相同的代码来构建复杂的应用程序。

TypeScript provides guarantees between different parts of the code on compile time. A compiler error typically tells you exactly where something went wrong and what exactly went wrong whereas a runtime error is accompanied by a stack trace that may be misleading and results on significant amount of time spent on debug work.

TypeScript在编译时在代码的不同部分之间提供保证。 编译器错误通常会告诉您确切的地方出了什么问题以及什么地方出了什么问题,而运行时错误伴随着堆栈跟踪,可能会引起误解,并导致大量的调试工作时间。

TypeScript专业人士 (TypeScript pros)

  1. Catch potential errors earlier in the development cycle.

    在开发周期的早期发现潜在的错误。
  2. Manage large codebases .

    管理大型代码库。
  3. Easier refactoring.

    简化重构。
  4. Make it easier to work in teams — When contracts in the code are stronger it is easier for different developers to move in and out of the codebase without unintentionally breaking things.

    使团队中的工作更容易-当代码中的合同更强大时,不同的开发人员可以更轻松地移入和移出代码库而不会无意间破坏工作。
  5. Documentation — Types inform some sort of documentation that your future self and that other developers can follow.

    文档-类型会通知您将来的自己和其他开发人员可以遵循的某种文档。

TypeScript缺点 (TypeScript cons)

  1. It’s something additional to learn — It’s a tradeoff between short-term slowdown and long-term improvement in efficiency and maintenance.

    这是需要学习的其他东西– 这是短期速度下降与效率和维护的长期改进之间的权衡。

  2. Type errors can be inconsistent.

    类型错误可能不一致。
  3. Configuration drastically changes its behaviour.

    配置会极大地改变其行为。

种类 (Types)

布尔型 (Boolean)

const isLoading: boolean = false;

(Number)

const decimal: number = 8;
const binary: number = 0b110;

(String)

const fruit: string = "orange";

数组 (Array)

Array types can be written in one of the two following ways:

可以通过以下两种方式之一来写数组类型:

// Most common
let firstFivePrimes: number[] = [2, 3, 5, 7, 11];
// Less common. Uses generic types (more on that later)
let firstFivePrimes2: Array<number> = [2, 3, 5, 7, 11];

元组 (Tuple)

Tuple types allow you to express an organised array where the type of a fixed number of elements is known. This means that you will get an error

元组类型允许您表达一个组织化的数组,其中已知固定数量的元素的类型。 这意味着您将得到一个错误

let contact: [string, number] = ['John', 954683];
contact = ['Ana', 842903, 'extra argument']  /* Error! 
Type '[string, number, string]' is not assignable to type '[string, number]'. */

任何 (Any)

any is compatible with any and all types in the type system, meaning that anything can be assigned to it and it can be assigned to anything. It gives you the power to opt-out of type checking.

any与类型系统中的所有类型兼容,这意味着可以将任何东西分配给它,也可以将它分配给任何东西。 它使您可以选择退出类型检查。

let variable: any = 'a string';
variable = 5;
variable = false;
variable.someRandomMethod(); /* Okay, 
someRandomMethod might exist at runtime. */

空洞 (Void)

void is the absence of having any type at all. It is commonly used as the return type of a function that do not return a value.

void是根本没有任何类型。 它通常用作不返回值的函数的返回类型。

function sayMyName(name: string): void {
  console.log(name);
}
sayMyName('Heisenberg');

决不 (Never)

The never type represents the type of values that never occur. For instance, never is the return type of a function which will always throw an exception or not reach its end point.

never类型表示永不出现的值的类型。 例如,函数的返回类型never抛出异常,也不会到达其终点。

// throws an exception
function error(message: string): never {
  throw new Error(message);
}

// unreachable end point
function continuousProcess(): never {
  while (true) {
      // ...
  }
}

未定义 (Null and Undefined)

Both undefined and null actually have their own types named undefinedand null, respectively. Much like void, they’re not extremely useful on their own but they become useful when used within union types (more on that in a bit)

实际上, undefinednull实际上都有自己的类型,分别名为undefinednull 。 就像void一样,它们本身并不是非常有用,但是当在联合类型中使用时它们会变得有用(更多内容)

type someProp = string | null | undefined;

未知 (Unknown)

TypeScript 3.0 introduces the unknown type which is the type-safe counterpart of any. Anything is assignable to unknown, but unknown isn’t assignable to anything but itself and any. No operations are permitted on an unknown without first asserting or narrowing to a more specific type.

TypeScript 3.0引入了未知类型,该类型是any的类型安全对应物。 任何东西都可以分配给unknown ,但是unknown不能分配给任何东西,只有它本身和any.东西都any. 在未先声明或缩小为更特定的类型之前,不允许对unknown进行任何操作。

type I1 = unknown & null;    // null
type I2 = unknown & string;  // string
type U1 = unknown | null;    // unknown
type U2 = unknown | string;  // unknown

类型别名 (Type Alias)

Type alias provides names for type annotations allowing you to use it in several places. They are created using the following syntax:

类型别名提供类型注释的名称,使您可以在多个地方使用它。 它们使用以下语法创建:

type Login = string;

联合类型 (Union Type)

TypeScript allows us to use more than one data type for a property. This is called union type.

TypeScript允许我们为属性使用多个数据类型。 这称为联合类型。

type Password = string | number;

交叉点类型 (Intersection Type)

Intersection types are types that combine properties of all of the member types.

交集类型是组合所有成员类型的属性的类型。

interface Person {
  name: string;
  age: number;
}

interface Worker {
  companyId: string;
}

type Employee = Person & Worker;

const bestOfTheMonth: Employee = {
  name: 'Peter'
  age: 39,
  companyId: '123456'

接口 (Interface)

Interfaces are like a contract between you and the compiler in which you specify in a single named annotation exactly what properties to expect with its respective type annotations.Side-note: Interfaces have zero runtime JS impact, it is used solely for type checking.

接口就像您和编译器之间的合同,在其中您可以在一个命名的批注中确切指定期望使用其各自的类型批注的属性。 旁注:接口对运行时JS的影响为零,它仅用于类型检查

  • You may declare optional properties marking those with an ?, meaning that objects of the interface may or may not define these properties.

    您可以声明可选 属性 ,用?标记这些属性 ? ,表示接口的对象可以定义也可以不定义这些属性。

  • You may declare read only properties, meaning that once a property is assigned a value, it cannot be changed.

    您可以声明只读 属性 ,这意味着一旦为属性分配了值,就无法更改它。

interface ICircle {
  readonly id: string;
  center: {
    x: number;
    y: number;
  },
  radius: number;
  color?: string;  // Optional property
}
  
const circle1: ICircle = {
  id: '001',
  center: { x: 0 },
  radius: 8,
};  /* Error! Property 'y' is missing in type '{ x: number; }' 
but required in type '{ x: number; y: number; }'. */

const circle2: ICircle = {
  id: '002',
  center: { x: 0, y: 0 },
  radius: 8,
}  // Okay

circle2.color = '#666';  // Okay
circle2.id = '003';  /* Error! 
Cannot assign to 'id' because it is a read-only property. */

扩展接口 (Extending Interfaces)

Interfaces can extend one or more interfaces. This makes writing interfaces flexible and reusable.

接口可以扩展一个或多个接口。 这使编写界面变得灵活且可重用。

interface ICircleWithArea extends ICircle {
  getArea: () => number;
}

const circle3: ICircleWithArea = {
  id: '003',
  center: { x: 0, y: 0 },
  radius: 6,
  color: '#fff',
  getArea: function () {
    return (this.radius ** 2) * Math.PI;
  },
};

实施接口 (Implementing an Interface)

A class implementing an interface needs to strictly conform to the structure of the interface.

实现接口的类需要严格遵循接口的结构。

interface IClock {
  currentTime: Date;
  setTime(d: Date): void;
}

class Clock implements IClock {
  currentTime: Date = new Date();
  setTime(d: Date) {
    this.currentTime = d;
  }
  constructor(h: number, m: number) { }
}

枚举 (Enums)

An enum (or enumeration) is a way to organise a collection of related values that can be numeric or string values.

enum (或枚举)是一种组织相关值集合的方法,这些相关值可以是数字或字符串值。

enum CardSuit {
  Clubs,
  Diamonds,
  Hearts,
  Spades
}

let card = CardSuit.Clubs;

card = "not a card suit"; /* Error! Type '"not a card suit"' 
is not assignable to type 'CardSuit'. */

Under the hood, enums are number-based by default. enum values start from zero and increment by 1 for each member.

在幕后,默认情况下,枚举是基于数字的。 enum值从零开始,每个成员递增1。

The JavaScript code generated by our previous example:

我们前面的示例生成JavaScript代码:

var CardSuit;
(function (CardSuit) {
  CardSuit[CardSuit["Clubs"] = 0] = "Clubs";
  CardSuit[CardSuit["Diamonds"] = 1] = "Diamonds";
  CardSuit[CardSuit["Hearts"] = 2] = "Hearts";
  CardSuit[CardSuit["Spades"] = 3] = "Spades";
})(CardSuit || (CardSuit = {}));

/**
 * Which results in the following object:
 * {
 *   0: "Clubs",
 *   1: "Diamonds",
 *   2: "Hearts",
 *   3: "Spades",
 *   Clubs: 0,
 *   Diamonds: 1,
 *   Hearts: 2,
 *   Spades: 3
 * }
 */

Alternatively enums can be initialised with string values which is a more readable approach.

另外,枚举可以用字符串值初始化,这是一种更具可读性的方法。

enum SocialMedia {
  Facebook = 'FACEBOOK',
  Twitter = 'TWITTER',
  Instagram = 'INSTAGRAM',
  LinkedIn = 'LINKEDIN'
}

反向映射 (Reverse Mapping)

enum supports reverse mapping which means we can access the value of a member and also a member name from its value.Going back to our CardSuit example:

enum支持反向映射,这意味着我们可以访问成员的值以及其值的成员名称。回到CardSuit示例:

const clubsAsNumber: number = CardSuit.Clubs; // 3
const clubsAsString: string = CardSuit[0];    // 'Clubs'

功能 (Functions)

You can add types to each of the parameters and then to the function itself to add a return type.

您可以向每个参数添加类型,然后向函数本身添加类型以添加​​返回类型。

function add(x: number, y: number): number {
  return x + y;
}

函数重载 (Function Overloads)

TypeScript allows you to declare function overloads. Basically, you can have multiple functions with the same name but different parameter types and return type. Consider the following example:

TypeScript允许您声明函数重载 。 基本上,您可以具有名称相同但参数类型和返回类型不同的多个函数。 考虑以下示例:

function padding(a: number, b?: number, c?: number, d?: any) {
  if (b === undefined && c === undefined && d === undefined) {
    b = c = d = a;
  }
  else if (c === undefined && d === undefined) {
    c = a;
    d = b;
  }
  return {
    top: a,
    right: b,
    bottom: c,
    left: d
  };
}

The meaning of each parameter changes based on how many parameters are passed into the function. Moreover, this function only expects one, two or four parameters. To create a function overload, you just declare the function header multiple times. The last function header is the one that is actually active within the function body but is not available to the outside world.

每个参数的含义根据传递给函数的参数数量而变化。 而且,此功能只需要一个,两个或四个参数。 要创建函数重载,只需多次声明函数头即可。 最后一个函数头是一个是函数体内确实有效,但不提供给外界。

function padding(all: number);
function padding(topAndBottom: number, leftAndRight: number);
function padding(top: number, right: number, bottom: number, left: number);
function padding(a: number, b?: number, c?: number, d?: number) {
  if (b === undefined && c === undefined && d === undefined) {
    b = c = d = a;
  }
  else if (c === undefined && d === undefined) {
    c = a;
    d = b;
  }
  return {
    top: a,
    right: b,
    bottom: c,
    left: d
  };
}

padding(1);       // Okay
padding(1,1);     // Okay
padding(1,1,1,1); // Okay
padding(1,1,1);   /* Error! No overload expects 3 arguments, but
overloads do exist that expect either 2 or 4 arguments. */

班级 (Classes)

You can add types to properties and method’s arguments

您可以将类型添加到属性和方法的参数

class Greeter {
  greeting: string;
  constructor(message: string) {
    this.greeting = message;
  }
  greet(name: string) {
    return `Hi ${name}, ${this.greeting}`;
  }
}

访问修饰符 (Access Modifiers)

Typescript supports public, private, protected modifiers, which determine the accessibility of a class member.

Typescript支持public private protected修饰符,它们确定类成员的可访问性。

  • A public member works the same as plain JavaScript members and is the default modifier.

    public成员的工作方式与普通JavaScript成员相同,并且是默认修饰符。

  • A private member cannot be accessed from outside of its containing class.

    不能从其包含类的外部访问private成员。

  • A protected member differ from a private as it can also be accessed within deriving classes.

    protected成员不同于私有成员,因为它也可以在派生类中进行访问。

| Accessible on  | public | protected | private |
| :------------- | :----: | :-------: | :-----: |
| class          |   yes  |    yes    |   yes   |
| class children |   yes  |    yes    |    no   |
| class instance |   yes  |     no    |    no   |

只读修饰符 (Readonly modifier)

A readonly property must be initialised at their declaration or in the constructor.

readonly属性必须在其声明或构造函数中进行初始化。

class Spider {
  readonly name: string;
  readonly numberOfLegs: number = 8;
  constructor (theName: string) {
    this.name = theName;
  }
}

参数属性 (Parameter properties)

Parameter properties lets you create and initialise a member in one place. They are declared by prefixing a constructor parameter with a modifier.

使用参数属性 ,您可以在一处创建和初始化成员。 通过在构造函数参数前面加上修饰符来声明它们。

class Spider {
  readonly numberOfLegs: number = 8;
  constructor(readonly name: string) {
  }
}

抽象 (Abstract)

The abstract keyword can be used both for classes and for abstract class methods.

abstract关键字可用于类和抽象类方法。

  • Abstract classes cannot be directly instantiated. They are mainly for inheritance where the class which extends the abstract class must define all the abstract methods.

    抽象类不能直接实例化。 它们主要用于继承,其中扩展抽象类的类必须定义所有抽象方法。

  • Abstract members do not contain an implementation, thus cannot be directly accessed. These members must be implemented in child classes (kinda like an interface)

    抽象成员不包含实现,因此不能直接访问。 这些成员必须在子类中实现(有点像接口)

类型断言 (Type Assertion)

TypeScript allows you to override its inferred types in any way you want to. This is used when you have a better understanding of a variable type than the compiler on its own.

TypeScript允许您以任何想要的方式覆盖其推断的类型。 当您比单独使用编译器更好地了解变量类型时,可以使用此方法。

const friend = {};
friend.name = 'John';  // Error! Property 'name' does not exist on type '{}'

interface Person {
  name: string;
  age: number;
}

const person = {} as Person;
person.name = 'John';  // Okay

Originally the syntax for type assertion was <type>

最初,类型断言的语法为<type>

let person = <Person> {};

But this created an ambiguity when used in JSX. Therefore it is recommended to use as instead.

但这在JSX中使用时产生了歧义。 因此,建议使用as替代。

Type assertion are usually used when migrating code from JavaScript and you may know a more accurate type of the variable than what is currently assigned. But assertion can be considered harmful.

从JavaScript迁移代码时通常使用类型断言,并且您可能知道比当前分配的更准确的变量类型。 但是断言可以被认为是有害的。

Let’s take a look at our Person interface from the previous example. Did you notice something wrong? If you noticed the missing property age, congratulations! The compiler might help you providing autocomplete for properties of Person but it will not complain if you miss any properties.

让我们看看上一个示例中的Person接口。 你有发现什么问题吗? 如果您注意到遗失的财产年龄 ,那就恭喜! 编译器可以帮助您为Person的属性提供自动完成功能,但是如果您错过任何属性,它都不会抱怨。

类型推断 (Type Inference)

TypeScript infers types of variables when there is no explicit information available in the form of type annotations.

当没有类型注释形式的显式信息时,TypeScript会推断变量的类型。

/**
 * Variable definitinon
 */
let a = "some string";
let b = 1;
a = b;  // Error! Type 'number' is not assignable to type 'string'.

// In case of complex objects, TypeScript looks for the most common type
// to infer the type of the object.
const arr = [0, 1, false, true];  // (number | boolean)[]


/**
 * Function return types
 */
function sum(x: number, y: number) {
  return x + y;  // infer to return a number
}

类型兼容性 (Type Compatibility)

Type compatibility is based on structural typing, which relates types based solely on their members.

类型兼容性基于结构类型,结构类型仅基于其成员来关联类型。

The basic rule for structural type is that x is compatible with y if y has at least the same members as x.

用于结构类型的基本规则是, x是兼容y如果y具有至少相同的部件x

interface Person {
  name: string;
}

let x: Person;  // Okay, despite not being an implementation of the Person interface
let y = { name: 'John', age: 20 };  // type { name: string; age: number }
x = y;

// Please note that x is still of type Person. 
// In the following example, the compiler will show an error message as it does not
// expect the property age in Person but the result will be as expected:
console.log(x.age); // 20

As y has a member name: string, it matched the required properties for the Person interface, meaning that x is a subtype of y. Thus, the assignment is allowed.

因为y具有成员name: string ,所以它匹配了Person接口的必需属性,这意味着xy的子类型。 因此,允许分配。

功能 (Functions)

Number of argumentsIn a function call you need to pass in at least enough arguments, meaning that extra arguments will not cause any errors.

参数数量在函数调用中,您至少需要传递足够的参数,这意味着多余的参数不会引起任何错误。

function consoleName(person: Person) {
  console.log(person.name);
}
consoleName({ name: 'John' });           // Okay
consoleName({ name: 'John', age: 20 });  // Extra argument still Okay

Return typeThe return type must contain at least enough data.

返回类型返回类型必须至少包含足够的数据。

let x = () => ({name: 'John'});
let y = () => ({name: 'John', age: 20 });
x = y;  // OK
y = x;  /* Error! Property 'age' is missing in type '{ name: string; }'
but required in type '{ name: string; age: number; }' */

类型防护 (Type Guard)

Type Guards allow you to narrow down the type of an object within a conditional block.

类型保护使您可以缩小条件块内对象的类型。

类型 (typeof)

Using typeof in a conditional block, the compiler will know the type of a variable to be different. In the following example TypeScript understand that outside the conditional block, x might be a boolean and the function toFixed cannot be called on it.

在条件块中使用typeof,编译器将知道变量的类型是不同的。 在下面的示例TypeScript中,我们了解到在条件块之外, x可能是布尔值,并且无法在其上调用toFixed函数。

function example(x: number | boolean) {
  if (typeof x === 'number') {
    return x.toFixed(2);
  }
  return x.toFixed(2); // Error! Property 'toFixed' does not exist on type 'boolean'.
}

实例 (instanceof)

class MyResponse {
  header = 'header example';
  result = 'result example';
  // ...
}
class MyError {
  header = 'header example';
  message = 'message example';
  // ...
}
function example(x: MyResponse | MyError) {
  if (x instanceof MyResponse) {
    console.log(x.message); // Error! Property 'message' does not exist on type 'MyResponse'.
    console.log(x.result);  // Okay
  } else {
    // TypeScript knows this must be MyError

    console.log(x.message); // Okay
    console.log(x.result);  // Error! Property 'result' does not exist on type 'MyError'.
  }
}

(in)

The in operator checks for the existence of a property on an object.

in运算符检查对象上是否存在属性。

interface Person {
  name: string;
  age: number;
}

const person: Person = {
  name: 'John',
  age: 28,
};

const checkForName = 'name' in person; // true

文字类型 (Literal Types)

Literals are exact values that are JavaScript primitives. They can be combined in a type union to create useful abstractions.

文字是JavaScript原语的精确值。 可以将它们合并为类型联合以创建有用的抽象。

type Orientation = 'landscape' | 'portrait';
function changeOrientation(x: Orientation) {
  // ...
}
changeOrientation('portrait'); // Okay
changeOrientation('vertical'); /* Error! Argument of type '"vertical"' is not 
assignable to parameter of type 'Orientation'. */

条件类型 (Conditional Types)

A conditional type describes a type relationship test and selects one of two possible types, depending on the outcome of that test.

条件类型描述类型关系测试,并根据该测试的结果选择两种可能的类型之一。

type X = A extends B ? C : D;

This means that if type A is assignable to type B, then X is the same type as C. Otherwise X is the same as type D;

这意味着,如果类型A可分配给类型B ,则XC相同。 否则XD;类型相同D;

通用类型 (Generic Types)

Generic type is a type that must include or reference another type in order to be complete. It enforce meaningful constraints between various variables.In the following example a function returns an array of whatever type you pass in.

泛型类型是必须包含或引用另一种类型才能完整的类型。 它在各个变量之间施加有意义的约束。在下面的示例中,函数返回您传入的任何类型的数组。

function reverse<T>(items: T[]): T[] {
  return items.reverse();
}
reverse([1, 2, 3]); // number[]
reverse([0, true]); // (number | boolean)[]

密钥 (keyof)

The keyof operator queries the set of keys for a given type.

keyof运算符查询给定类型的键集。

interface Person {
  name: string;
  age: number;
}
type PersonKeys = keyof Person; // 'name' | 'age'

映射类型 (Mapped Types)

Mapped Types allow you to create new types from existing ones by mapping over property types. Each property of the existing type is transformed according to a rule that you specify.

映射类型允许您通过映射属性类型从现有类型创建新类型。 现有类型的每个属性都根据您指定的规则进行转换。

部分的 (Partial)

type Partial<T> = {
  [P in keyof T]?: T[P];
}
  • The generic Partial type is defined with a single type parameter T.

    通用Partial类型由单个类型参数T定义。

  • keyof T represents the union of all property names of T as string literal types.

    keyof T代表的所有属性名的工会T的字符串文字类型。

  • [P in keyof T]?: T[P] denotes that the type of each property P of type T should be optional and transformed to T[P].

    [P in keyof T]?: T[P]表示类型T的每个属性P的类型应该是可选的,并转换为T[P]

  • T[P] represents the type of the property P of the type T.

    T[P]表示类型T的属性P的类型。

只读 (Readonly)

As we have covered in the Interface section, TypeScript allows you to create readonly properties. There is a Readonly type that takes a type T and sets all of its properties as readonly.

正如我们在“接口”部分中所述,TypeScript允许您创建只读属性。 有一个Readonly类型,它采用类型T并将其所有属性设置为只读。

type Readonly<T> = {
  readonly [P in keyof T]: T[P];
};

排除 (Exclude)

Exclude allows you to remove certain types from another type. Excludefrom T anything that is assignable to T.

Exclude允许您从其他类型中删除某些类型。 从T Exclude任何可分配给T东西。

/**
 * type Exclude<T, U> = T extends U ? never : T;
 */
type User = {
  _id: number;
  name: string;
  email: string;
  created: number;
};

type UserNoMeta = Exclude<keyof User, '_id' | 'created'>

(Pick)

Pick allows you to pick certain types from another type. Pick from Tanything that is assignable to T.

Pick允许您从其他类型中选择某些类型。 从T Pick可分配给T任何东西。

/**
 * type Pick<T, K extends keyof T> = {
 *   [P in K]: T[P];
 *  };
 */
type UserNoMeta = Pick<User, 'name' | 'email'>

推断 (infer)

You can use the infer keyword to infer a type variable within the extendsclause of a conditional type. Such inferred type variable can only be used in the true branch of the conditional type.

您可以使用infer关键字来推断条件类型的extends子句中的类型变量。 此类推断的类型变量只能在条件类型的真实分支中使用。

返回类型 (ReturnType)

Gets the return type of a function.

获取函数的返回类型。

/**
 * Original TypeScript's ReturnType
 * type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
 */
type MyReturnType<T> = T extends (...args: any) => infer R ? R : any;

type TypeFromInfer = MyReturnType<() => number>;  // number
type TypeFromFallback = MyReturnType<string>;     // any

Let’s break down MyReturnType:

让我们分解MyReturnType

  • The return type of T is …

    T的返回类型为…

  • First of all, is T a function?

    首先, T是一个函数吗?

  • If so, then the type resolves to the inferred return type R.

    如果是这样,则该类型解析为推断的返回类型R

  • Otherwise the type resolves to any.

    否则,类型解析为any

https://basarat.gitbooks.io/typescript/

https://basarat.gitbooks.io/typescript/

https://www.typescriptlang.org/docs/home.html

https://www.typescriptlang.org/docs/home.html

https://www.tutorialsteacher.com/typescript

https://www.tutorialsteacher.com/typescript

https://github.com/dzharii/awesome-typescript

https://github.com/dzharii/awesome-typescript

https://github.com/typescript-cheatsheets/react-typescript-cheatsheet

https://github.com/typescript-cheatsheets/react-typescript-cheatsheet



In order to study and give TypeScript a try I’ve build a simple CurrencyConverter app using TS and React-Native with hooks. You can check this project here.

为了研究和尝试TypeScript,我使用TS和带有钩子的React-Native构建了一个简单的CurrencyConverter应用程序。 您可以在此处检查该项目。

Thanks and congratulations for reading up to this point! If you have any thoughts on this, feel free to leave a comment.

感谢并祝贺您阅读本文! 如果对此有任何想法,请随时发表评论。

You can find me on Twitter.

您可以在Twitter上找到我。

翻译自: https://www.freecodecamp.org/news/the-definitive-typescript-handbook/

typescript

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值