Exploring TypeScript Type Annotations - Built-in Typesgit
关于github
做者: zhilidali数组
欢迎来到 《探索 TypeScript 类型注解》 系列教程。 开篇咱们(从新)认识了 TypeScript,本篇探索 TypeScript 的内置类型。函数
正文ui
let foo = 'TS';
let bar: boolean = foo; // Error: Type 'string' is not assignable to type 'boolean'.ts(2322)
复制代码
Type Annotationsthis
语法 : : type
。如 :boolean
。spa
做用 :约定变量的数据类型。如约定 bar
为布尔值。rest
好处 :code
Type 'string' is not assignable to type 'boolean'
。bar
上,会提示 let foo: string
。Type Inference
foo
的类型没有显示指定,TypeScript 会根据上下文自行推断。 let foo = 'TS';
与 let foo: string = TS;
是等价的。
Primitive Type
- 支持
boolean
、number
、string
、symbol
、undefined
、null
基础类型- 新增
void
、never
基础类型- 新增
any
类型
TypeScript 支持 JavaScript 的基础类型
let tsBoo: boolean = false;
let tsNum: number = 0x10;
let tsStr: string = 'ts';
let tsSym: symbol = Symbol('ts');
let tsUnInit: undefined;
let tsEmpty: null = null;
复制代码
TS 还支持基本包装类型
Boolean
、Number
、String
、Symbol
,基本类型为基本包装类型的子类型。
// 基本包装类型 Boolean
let tsBool1: Boolean = new Boolean();
// 基本类型为基本包装类型的子类型
let tsBool2: Boolean = false;
复制代码
void
void
标识函数没有返回值(返回 undefined)。function tsVoid(): void {
// 没有 return,即 `return undefined` 时使用
}
复制代码
void VS. undefined
- 在 JS 中,void 为操做符,总返回 undefined; 而 undefined 在宽松模式下,可做变量。
- 在 TS 中,
void
做为返回值类型时,可用其余类型替换,而undefined
不行。
function bar(callback: () => void) {}
function baz(callback: () => undefined) {}
// foo 返回 number 类型
function foo(): number { return 1; }
bar(foo); // foo 返回的 number 类型替换为 void 类型
baz(foo); // Error:`Type 'number' is not assignable to type 'undefined'.(2345)`)
复制代码
never
never
标识函数不会 return。如抛出异常或生成器函数存在 while(true){}
。never
是全部类型的子类型,可赋给任意类型。function tsNever1(): never {
throw new Error('Throw Exception or never return');
}
function *tsNever2(): never {
while(true) {
// ...
}
}
复制代码
never
前面说过,never
是全部类型的子类型。在 tsconfig.json 中:
strictNullChecks
为 false 时,可直接赋给任意类型。strictNullChecks
为 true 时,never
需在赋值后才能使用。let tsNever: never;
let tsNum: number;
let f = function():never {throw 'never'};
tsNum = tsNever; // `strictNullChecks` 为 true 时,提示 Error。
tsNever = f();
tsNum = tsNever;
复制代码
any
TS 还增长了 any
类型,当不但愿 TS 检查时使用。
any
类型或 any
类型赋值给任意类型 (never 除外) 均不会报错。 any
let tsAny: any = 'any value';
let tsNum: number = tsAny; // 可赋值给任意类型
tsAny = true; // 可被赋值任意类型
复制代码
undefined && null
undefined
、null
为子类型。在 tsconfig.json 中:
strictNullChecks
为 false 时,undefined、null 可赋值给除never
外的任意类型的变量。strictNullChecks
为 true 时,undefined 只能赋值给 void
、any
类型的变量。let tsNum: number = undefined;
let tsVoid: void = undefined;
复制代码
Reference Type
- 支持 Object、Array、Date、RegExp、Error、Function、Class 等类型
- 新增 Tuple、Enum 类型
object
描述(只读)对象类型
let tsObj1: object = { a: 1 };
tsObj1.x = 2; // Error: Property 'x' does not exist on type 'object'.
复制代码
三种定义方式(后两种详见下篇):
[]
,即 T[]
Array<T>
ReadonlyArray<T>
interface
定义类型let tsArr1: string[] = ['foo'];
// 数组泛型
let tsArr2: Array<string> = ['foo'];
let readonlyArr: ReadonlyArray<string> = ['foo']; // 只读数组
// 数值索引签名
interface IdxType { [index: number]: string }
let tsArr3: IdxType = ['foo'];
复制代码
元组:已知元素数量和类型的数组
let tsTuple: [string, number] ;
tsTuple = ['foo', 1];
tsTuple = [1, 'foo']; // Error
tsTuple[0].toUpperCase();
tsTuple[1].toUpperCase(); // Error
// 访问越界元素时会使用联合类型: (string | number)
tsTuple[2] = 'bar';
tsTuple[2] = 2;
tsTuple[2] = false; // Error
复制代码
枚举: 定义一组命名常量(枚举成员只读)
// Numeric enums
enum Color { Red = 2, Green, Blue };
/* 编译器反向映射为 var Color; (function(Color) { Color[(Color["Red"] = 2)] = "Red"; Color[(Color["Green"] = 3)] = "Green"; Color[(Color["Blue"] = 4)] = "Blue"; })(Color || (Color = {})); */
let num: Color = Color.Green; // 3
let str: string = Color[3]; // Green
// String enums
enum Response { No = 'NO', Yes = 'YES' }
// Heterogeneous enums
enum HeterogeneousEnum { No = 0, Yes = "YES" }
复制代码
let date: Date = new Date();
let reg: RegExp = /\.ts$/;
let err: Error = new Error('error');
复制代码
描述参数和返回值类型
(paramter: T): U
描述函数定义: (paramter: T) => U
描述函数变量
// 函数声明
function fn1(s: string): string {
return s;
}
// 箭头函数表达式
let fn2 = (s: string): string => s;
// 函数变量 fn
let fn3: (str: string) => string = fn2;
复制代码
参数
foo?: T
foo: T = value
...rest: T[]
let fn2 = (
s: string, // 必选参数
b: string = '', // 默认参数
c?: string, // 可选参数;位于必选参数后面
...d: string[] // 剩余参数;位于参数最后
): string => s;
复制代码
重载
// Overload
function reverse(x: number): number;
function reverse(x: string): string;
function reverse(x: number | string): number | string {
if (typeof x === 'number') {
return Number(x.toString().split('').reverse().join(''));
} else if (typeof x === 'string') {
return x.split('').reverse().join('');
}
}
复制代码
TS 保留并增添了功能 (目前 TS 与 ES 的类表现不一致)
ES :
class F {
constructor(msg) {
this.foo = msg;
}
getFoo() {
return this.foo;
}
}
class B extends F {
constructor(msg) {
super(msg);
}
getFoo() {
return 'b' + super.getFoo();
}
}
复制代码
TS :
class F {
foo: string
constructor(msg: string) {
this.foo = msg;
}
getFoo() {
return this.foo;
}
}
class B extends F {
constructor(msg: string) {
super(msg);
}
getFoo() {
return 'b' + super.getFoo();
}
}
复制代码
结语 本篇介绍了 TS 的内置类型,下一篇介绍如何自定义类型。
本做品采用知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议进行许可。