TypeScript 高级类型整理

来源:互联网 发布:linux基础试题 编辑:程序博客网 时间:2024/04/29 19:10

一、交叉类型(Intersection Types)

交叉类型是奖多个类型合并为一个类型。这往我们可以把多个现有的多种类型叠加成为一种类型,它包含了所需的所有类型的特性。主要用于多个对象的混合。

例如, Person & Serializable & Loggable同时是PersonSerializableLoggable。 就是说这个类型的对象同时拥有了这三种类型的成员。

将多个对象混合成一个交叉类型,这种操作用的情况应该比较少

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;}class Person {    constructor(public name: string) { }}interface Loggable {    log(): void;}class ConsoleLogger implements Loggable {    log() {        // ...    }}var jim = extend(new Person("Jim"), new ConsoleLogger());var n = jim.name;jim.log();

二、联合类型(UnionTypes)

联合类型与交叉类型很有关联,但是使用上却完全不同。

联合类型,将类型使用 | 关联在一起。

联合类型,可以将一个变量指定为已知的默写类型,可以将函数的返回值指定为已知的默写类型。

当前一个函数需要传入string类型或者number类型,可以使用any,同样更推荐使用联合类型。

function padLeft(value: string, padding: string | number) {    // ...}let indentedString = padLeft("Hello world", true); // errors during compilation
返回类型中,使用联合类型

interface Bird {    fly();    layEggs();}interface Fish {    swim();    layEggs();}function getSmallPet(): Fish | Bird {    // ...}let pet = getSmallPet();pet.layEggs(); // okaypet.swim();    // errors

对于类型的私有部分

let pet=getSmallPet();pet.layEggs();//对于两种类型的个字的特有的方法,编译异常// pet.fly();// pet.swim();

1.类型保护与区分类型,使用类型断言处理<>或者as

//使用类型断言,判断类型的理由部分//使用类型断言,编写代码的时候有代码提示if((<Bird>pet).fly){    (pet as Bird).fly();}else{    (<Fish>pet).swim();}

2.用户自定义类型区分,使用 is 谓词

类型判断方法

function isFish(pet: Fish | Bird): pet is Fish {    return (<Fish>pet).swim !== undefined;}
 谓词为 parameterName is Type这种形式,parameterName必须是来自于当前函数签名里的一个参数名。
3.typeof 类型保护,主要用于判断基础类型

只有两种形式能被识别:typeof v === "typename"typeof v !== "typename""typename"必须是"number""string""boolean""symbol"。 但是TypeScript并不会阻止你与其它字符串比较,语言不会把那些表达式识别为类型保护。

function padLeft(value: string, padding: string | number) {    if (typeof padding === "number") {        return Array(padding + 1).join(" ") + value;    }    if (typeof padding === "string") {        return padding + value;    }    throw new Error(`Expected string or number, got '${padding}'.`);}
4.instanceof 类型保护

instanceof类型保护是通过构造函数来细化类型的一种方式。
1.instanceof要求判断类型有构造函数,也就是对类类型可判断,如果是接口类型则不能使用

2.编译器会识别instanceof,在编写代码识别的时候,会有自动提示

interface Padder {    getPaddingString(): string;}class SpaceRepeatingPadder implements Padder {    repeat: string = '张三丰';    getPaddingString() {        return 'space';    }}class StringPadder implements Padder {    age: number = 15,    getPaddingString() {        return 'string';    }}function getRandomPadder(): Padder {    return Math.random() < 0.5 ?        new SpaceRepeatingPadder() :        new StringPadder();}let padder: Padder = getRandomPadder();//使用 instanceof 类型保护//编译器自动识别,写代码时自动根据类型提示if (padder instanceof SpaceRepeatingPadder) {    console.log(padder.repeat);}if (padder instanceof StringPadder) {    console.log(padder.age);}
5.可以为null的类型,可选参数、可选属性

TypeScript具有两种特殊的类型,nullundefined,它们分别具有值null和undefined. 我们在基础类型一节里已经做过简要说明。 默认情况下,类型检查器认为 nullundefined可以赋值给任何类型。
--strictNullChecks标记可以解决此错误:当你声明一个变量时,它不会自动地包含nullundefined

默认情况下这个属性不启用。

 你可以使用联合类型明确的包含它们:

let s = "foo";s = null; // 错误, 'null'不能赋值给'string'let sn: string | null = "bar";sn = null; // 可以sn = undefined; // error, 'undefined'不能赋值给'string | null'
使用了--strictNullChecks,可选参数会被自动地加上| undefined:

默认情况下这个属性是启用的。

function f(x: number, y?: number) {    return x + (y || 0);}f(1, 2);f(1);f(1, undefined);f(1, null); // error, 'null' is not assignable to 'number | undefined'

三、类型别名 type 

类型别名会给一个类型启一个新的名字。

器别名不会新建一个类型。

类型别名可以使用泛型。

不能被extendsimplements扩展。

type Name = string;type NameResolver = () => string;type NameOrResolver = Name | NameResolver;function getName(n: NameOrResolver): Name {    if (typeof n === 'string') {        return n;    }    else {        return n();    }}

四、字符串字面量类型

字符串字面量类型允许你指定字符串必须的固定值。在实际应用中,字符串字面量类型可以与联合类型,类型保护和类型别名很好的配合。

通过结合使用这些特性,你可以实现类似枚举类型的字符串

type Easing = "ease-in" | "ease-out" | "ease-in-out";class UIElement {    animate(dx: number, dy: number, easing: Easing) {        if (easing === "ease-in") {            // ...        }        else if (easing === "ease-out") {        }        else if (easing === "ease-in-out") {        }        else {            // error! should not pass null or undefined.        }    }}let button = new UIElement();button.animate(0, 0, "ease-in");button.animate(0, 0, "uneasy"); // error: "uneasy" is not allowed here

五、可辨识联合(Discriminated Unions)

感觉不太好用。

多态的this类型

多态的this类型表示的是某个包含类或接口的子类型。 这被称做 F-bounded多态性。 它能很容易的表现连贯接口间的继承,比如。 在计算器的例子里,在每个操作之后都返回 this类型:

class BasicCalculator {    public constructor(protected value: number = 0) { }    public currentValue(): number {        return this.value;    }    public add(operand: number): this {        this.value += operand;        return this;    }    public multiply(operand: number): this {        this.value *= operand;        return this;    }    // ... other operations go here ...}let v = new BasicCalculator(2)            .multiply(5)            .add(1)            .currentValue();

六、索引类型(Index Types)

暂时忽略

七、映射类型

暂时忽略


更多:

TypeScript 类型兼容性整理

TypeScript 类型推论整理

TypeScript 枚举使用整理

原创粉丝点击