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 國際許可協議進行許可。