Intersection Types 組合類型
比如 Serializable
和 Deserializable
可以通過 &
組合出一樣新的類型:Serializable & Deserializable
降允,也可以看作是一個匿名的擴展類型犁嗅。
因為如果上面兩個類型是接口類型的話童社,我們可以這樣聲明一個具名的新類型:
interface Json extends Serializable,Deserializable {}
使用實例:
function extend<T,U>(first:T,second:U): T&U{
let result = <T&U>{};
for(let id in first){
(<any>result)[id] = (<any>first)[id];
}
for(let id in second){
if(!result.hasOwnProperty(id)){
(<any>result)[id] = (<any>second)[id];
}
}
return result;
}
Union Types 聯(lián)合類型
可以通過 |
聯(lián)合多個類型,創(chuàng)建出聯(lián)合類型旦装,例如: number|string
使用示例:
/**
* Takes a string and adds "padding" to the left.
* If 'padding' is a string, then 'padding' is appended to the left side.
* If 'padding' is a number, then that number of spaces is added to the left side.
*/
function padLeft(value: string, padding: string | number) {
// ...
}
注意: 對于聯(lián)合類型的對象棒妨,我們只可以訪問聯(lián)合類型中各個類型存在交集的方法。要訪問某一子類型的方法陪腌,需要先通過類型轉換烟瞧。
類型防御
- 用戶自定義的類型防御
TS 提供了類型 kotlin 中經過檢查的smartcast 的功能砾赔。
只要在類型判斷函數中返回 parameterName is Type
這樣的斷言暴心。即可
function isFish(pet: Fish|Bird): pet is Fish{
return (<Fish>pet).swim !== undefined;
}
// 經過類型判斷之后甚亭,pet 可以直接當某一聯(lián)合類型的字類型對象使用暇唾。
if(isFish(pet)){
pet.swim()
}else{
pet.fly();
}
- 使用
typeof
的類型防御
支持兩種寫法:typeof v === "typename"
和typeof v!== "typename"
枯冈。
typename
只能是"number"
,"string"
,"boolean"
,"symbol"
琢感。如果是其他的話丢间,TS 不會將其當作是類型防御斷言。
使用 typeof
類型防御改寫 padLeft
function isNumber(x:any): x is number{
return typeof x === "number";
}
function isString(x:any): x is string{
return typeof x === "string";
}
function padLeft(value: string, padding: string | number) {
if (isNumber(padding)) {
return Array(padding + 1).join(" ") + value;
}
if (isString(padding)) {
return padding + value;
}
throw new Error(`Expected string or number, got '${padding}'.`);
}
- 使用
instanceof
的類型防御
使用instanceof
也會有智能轉換的效果驹针,instanceof
右邊只能是構造函數烘挫。
類型別名
可以使用 type
創(chuàng)建新的類型或類型別名.
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
function getName(n:NameOrResolver):Name{
if(typeof n == "string"){
return n;
}else{
return n();
}
}
別名聲明也可以使用泛型和組合類型及聯(lián)合類型。
type Container<T> = { value:T};
type Tree<T> = {
value: T;
left : Tree<T>;
right: Tree<T>;
}
type LinkedList<T> = T & { next: LinkedList<T> };
一些特殊用法示例:
字符串聯(lián)合
type Easing = "ease-in" | "ease-out" | "ease-in-out";
這將限制Easing
類型只能取上面的三個值柬甥。有點類似枚舉的意思饮六。數值聯(lián)合,類型字符串聯(lián)合 。
type DieCode = 1|2|3|4|5|6;
其他類型聯(lián)合苛蒲。
type Shape = Square | Rectangle | Circle;
現在Shape
類型將可以使用上面聯(lián)合類型的屬性的交集卤橄。
Index types 索引類型
keyof T
例如:
interface Person{
name:string,
age:number
}
let personProps: keyof Person; // 相當于 'name' | 'age'
看一下下面的使用示例:
function getProperty<T, K extends keyof T>(o: T, name: K): T[K] {
return o[name]; // o[name] is of type T[K]
}
T[K]
是一個動態(tài)類型。表示 T
類開中 名為 K
的屬性的類型臂外。
Mapped types 映射類型
type Keys = 'options1' | 'option2';
type Flags = { [K in Keys] : boolean };
// 相當于
type Flags = {
option1: boolean;
option2: boolean;
}
只讀代理包裝:
type Readonly<T> = {
readonly [P in keyof T]: T[P];
}
type ReadonlyPerson = Readonly<Person>;
參考 :Advanced types