You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
letobj: any={x: 0};// None of the following lines of code will throw compiler errors.// Using `any` disables all further type checking, and it is assumed // you know the environment better than TypeScript.obj.foo();obj();obj.bar=100;obj="hello";constn: number=obj;
// No type annotation needed -- 'myName' inferred as type 'string'letmyName="Alice";
Functions
在 Typescript 中,允许你同时指定函数参数以及返回值的类型:
参数类型注释
// Parameter type annotationfunctiongreet(name: string){console.log("Hello, "+name.toUpperCase()+"!!");}// Would be a runtime error if executed!greet(42);
// No type annotations here, but TypeScript can spot the bugconstnames=["Alice","Bob","Eve"];// Contextual typing for functionnames.forEach(function(s){console.log(s.toUppercase());// Property 'toUppercase' does not exist on type 'string'. Did you mean 'toUpperCase'?});// Contextual typing also applies to arrow functionsnames.forEach((s)=>{console.log(s.toUppercase());// Property 'toUppercase' does not exist on type 'string'. Did you mean 'toUpperCase'?});
Object Types
对象类型是除基本类型之外最常见的类型,定义一个对象类型,只需简单的罗列出它的属性和属性类型:
// The parameter's type annotation is an object typefunctionprintCoord(pt: {x: number;y: number}){console.log("The coordinate's x value is "+pt.x);console.log("The coordinate's y value is "+pt.y);}printCoord({x: 3,y: 7});
定义对象类型,使用 ; 或 , 分隔符都是合法的
可选属性:
functionprintName(obj: {first: string;last?: string}){// ...}// Both OKprintName({first: "Bob"});printName({first: "Alice",last: "Alisson"});
functionprintName(obj: {first: string;last?: string}){// Error - might crash if 'obj.last' wasn't provided!console.log(obj.last.toUpperCase());// Object is possibly 'undefined'.if(obj.last!==undefined){// OKconsole.log(obj.last.toUpperCase());}// A safe alternative using modern JavaScript syntax:console.log(obj.last?.toUpperCase());}
Union Types
一种方式结合不同的类型是使用联合类型:
functionprintId(id: number|string){console.log("Your ID is: "+id);}// OKprintId(101);// OKprintId("202");// ErrorprintId({myID: 22342});// Argument of type '{ myID: number; }' is not assignable to parameter of type 'string | number'.// Type '{ myID: number; }' is not assignable to type 'number'.
functionprintId(id: number|string){console.log(id.toUpperCase());// Property 'toUpperCase' does not exist on type 'string | number'.// Property 'toUpperCase' does not exist on type 'number'.}
functionprintId(id: number|string){if(typeofid==="string"){// In this branch, id is of type 'string'console.log(id.toUpperCase());}else{// Here, id is of type 'number'console.log(id);}}
另一个例子是 Array.isArray:
functionwelcomePeople(x: string[]|string){if(Array.isArray(x)){// Here: 'x' is 'string[]'console.log("Hello, "+x.join(" and "));}else{// Here: 'x' is 'string'console.log("Welcome lone traveler "+x);}}
如果联合类型中的成员同时具有某个方法或属性,不需要通过 Narrowing 也可以直接访问:
// Return type is inferred as number[] | stringfunctiongetFirstThree(x: number[]|string){returnx.slice(0,3);}
Type Aliases
类型别名仅仅是给希望多次使用的任意类型一个名字,语法如下:
typePoint={x: number;y: number;};// Exactly the same as the earlier examplefunctionprintCoord(pt: Point){console.log("The coordinate's x value is "+pt.x);console.log("The coordinate's y value is "+pt.y);}printCoord({x: 100,y: 100});
可以给任意类型赋予一个类型别名,不仅仅是对象类型。比如给联合类型赋予别名:
typeID=number|string;
需要注意,别名仅仅是别名,无法通过别名给同样的类型定义一个不同的、有区别的版本。
Interfaces
另一种方式给一个对象类型起名是通过接口定义:
interfacePoint{x: number;y: number;}functionprintCoord(pt: Point){console.log("The coordinate's x value is "+pt.x);console.log("The coordinate's y value is "+pt.y);}printCoord({x: 100,y: 100});
Type Aliases 和 Interfaces 大多数情况非常类似,主要区别是别名无法通过重复定义的方式来新增属性:
constx="hello"asnumber;// Conversion of type 'string' to type 'number' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
有时候,这条规则过于保守,禁止了一些更复杂但有效的强制转换。解决办法是通过两次类型断言(先断言为 any 或 unknown):
consta=(exprasany)asT;
Literal Types
除了基本类型 string 和 number,有时候需要指定某个更具体的字符串或数字
一种方式是 const:
letchangingString="Hello World";changingString="Olá Mundo";// Because `changingString` can represent any possible string, that// is how TypeScript describes it in the type system// let changingString: stringconstconstantString="Hello World";// Because `constantString` can only represent 1 possible string, it// has a literal type representation// const constantString: "Hello World"
鉴于通常一个可变的变量不会只持有一个值,以下这种方式不是很有价值:
letx: "hello"="hello";// OKx="hello";// Type '"howdy"' is not assignable to type '"hello"'.x="howdy";
如果通过联合类型结合字面量类型,可以表达出一个非常有用的概念:例如函数只能接受某些确定的值
functionprintText(s: string,alignment: "left"|"right"|"center"){// ...}printText("Hello, world","left");printText("G'day, mate","centre");// Argument of type '"centre"' is not assignable to parameter of type '"left" | "right" | "center"'.
interfaceOptions{width: number;}functionconfigure(x: Options|"auto"){// ...}configure({width: 100});configure("auto");configure("automatic");// Argument of type '"automatic"' is not assignable to parameter of type 'Options | "auto"'.
functionhandleRequest(url: string,method: "GET"|"POST")constreq={url: "https://example.com",method: "GET"};handleRequest(req.url,req.method);// Argument of type 'string' is not assignable to parameter of type '"GET" | "POST"'.
// Creating a bigint via the BigInt functionconstoneHundred: bigint=BigInt(100);// Creating a BigInt via the literal syntaxconstanotherHundred: bigint=100n;
symbol:通过 Symbol() 函数创建一个全局独一无二的引用类型:
constfirstName=Symbol("name");constsecondName=Symbol("name");if(firstName===secondName){// This condition will always return 'false' since the types 'typeof firstName' and 'typeof secondName' have no overlap.// Can't ever happen}
The text was updated successfully, but these errors were encountered:
string, number, boolean
在 Typescript 存在3个常用的基本类型:
string
,number
,boolean
。它们的命名和 Javascript 中对一个变量使用typeof
操作符获得的值相同Arrays
想要指定一个数组的元素类型(比如
[1, 2, 3]
),可以使用以下两种语法:number[]
Array<number>
any
在 Typescript 中存在一个特殊类型:
any
,一旦某个变量被声明为any
,Typescript 会在编译阶段放弃对它进行类型检查这同时意味着,可以读写这个变量的任意属性、函数调用该变量、将任何类型的值复制给该变量或将该变量赋值给任意类型的其他变量
Type Annotations on Variables
如果通过
var
let
const
来声明一个变量,那么类型注释是可选的:Functions
在 Typescript 中,允许你同时指定函数参数以及返回值的类型:
和变量类似,通常不需要对函数返回值进行类型注释,因为 Typescript 会根据
return
语句进行类型推论匿名函数会有些不同,Typescript 会根据匿名函数如何被调用来决定此函数入参的类型:
Object Types
对象类型是除基本类型之外最常见的类型,定义一个对象类型,只需简单的罗列出它的属性和属性类型:
可选属性:
在 Javascript 中,如果在对象上访问一个不存在的属性,会得到值
undefined
而不是一个运行时报错。鉴于此,在使用可选属性时,需要考虑到undefined
:Union Types
一种方式结合不同的类型是使用联合类型:
当在 Typesccript 中使用联合类型,只有当联合类型的每个成员都拥有某个方法和属性时,才允许访问:
解决办法是通过代码
narrow(变窄)
联合类型。Narrowing
通常发生在 Typescript 能通过代码结构确定一个更特定的类型时:另一个例子是
Array.isArray
:如果联合类型中的成员同时具有某个方法或属性,不需要通过
Narrowing
也可以直接访问:Type Aliases
类型别名仅仅是给希望多次使用的任意类型一个名字,语法如下:
可以给任意类型赋予一个类型别名,不仅仅是对象类型。比如给联合类型赋予别名:
Interfaces
另一种方式给一个对象类型起名是通过接口定义:
Type Aliases
和Interfaces
大多数情况非常类似,主要区别是别名无法通过重复定义的方式来新增属性:interface
type
(通过交集)interface
新增字段:type
新增字段:Type Assertions
某些情况下,你会比 Typescript 更了解某个值的类型信息。例如通过
document.getElementById
,Typescript 只知道会返回一个HTMLElement
类型的值,但是你可能知道你的页面上会返回一个HTMLCanvasElement
类型的值。这种场景下,可以使用类型断言来指定一个更特定的类型:
和类型注释一样,类型断言会被编译器移除,不会影响代码运行时
另一种方式使用类型断言是通过尖括号语法(
.tsx
文件不适用):Typescript 仅允许通过类型断言将类型转换为更具体或更不具体的类型。该规则可防止出现“不可能”的强制转换:
有时候,这条规则过于保守,禁止了一些更复杂但有效的强制转换。解决办法是通过两次类型断言(先断言为
any
或unknown
):Literal Types
除了基本类型
string
和number
,有时候需要指定某个更具体的字符串或数字一种方式是
const
:鉴于通常一个可变的变量不会只持有一个值,以下这种方式不是很有价值:
如果通过联合类型结合字面量类型,可以表达出一个非常有用的概念:例如函数只能接受某些确定的值
数字的字面量类型工作方式是一样的:
当然,也可以结合字面量类型和非字面量类型:
在定义一个对象时,Typescript 不会将该对象的属性推论为字面量类型,例如以下例子中
counter
被推论为number
类型而不是0
类型:考虑如下场景,
req.method
被推论为string
,在req
被初始化,和handleRequest
被调用之间,该值可能会被重新赋予一个字符串,Typescript会认为这是个错误:解决办法如下:
as const
将整个对象所有属性转变为字面量类型:null and undefined
在 Javascript 中,有两个基本值
null
、undefined
代表缺省或未初始化,Typescript 中同样有两个名字一致相应的类型,这两种类型如何表现取决于strictNullChecks
选项是否打开。strictNullChecks
关闭时:null
、undefined
值可以正常访问,也可以用来赋予声明为任意类型的变量或属性。然而缺少了类型检查,这些值会导致大量bug,推荐打开strictNullChecks
选项strictNullChecks
打开时:当一个值是
null
或undefined
,在使用这个值之前必须确保这个值拥有相应的属性或方法,类似于通过Narrowing
来使用可选属性:Non-null
类型断言操作符:Typescript 中有一个特殊的语法,用来移除某个类型的
null
和undefined
,即表示,此值不可能为null
或undefined
:和其他类型断言一样,这段代码不会对运行时产生影响,因此在使用
!
操作符前,必须确保你知道这个值真的不可能是null
或undefined
Enums
枚举类型是对 Javascript 的一个扩展,允许给一组可以命名的值增加描述(太绕了,看例子),和其他 Typescript 特性不同,枚举类型是一个运行时的特性:
编译后的 Javascript :
Less Common Primitives
bigint
:ES2020之后,推出的一个新基本类型,用来存储一个非常大的整数symbol
:通过Symbol()
函数创建一个全局独一无二的引用类型:The text was updated successfully, but these errors were encountered: