【Typescript】- Typescript进阶

1,118 阅读3分钟

「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战

前言

我们在学习 Typescript 进阶知识之前,先提前温习下前面的知识: Typescript预备知识Typescript基础知识

进阶知识

类型操作

keyof (索引类型查询操作符)是在TS2.1引入的。它获取类型上所有已知、public的键对应的类型联合。

image.png

我们下面来看下简单类型的keyof:

type K1 = keyof unknown;// nerver
type K3 = keyof undefined;// nerver
type K4 = keyof void;// nerver
type K5 = keyof null;// nerver
type K11 = keyof object;// nerver
type K12 = keyof nerver;// nerver

type K2 = typeof any;// string|number|symbol

// keyof 可以将 number、biginit、booleanstring、symbol 转化为对应的 interface,输出相应的方法字符串
// "toString" | "toFixed" | "toEx" | "toExponential" | "toPrecision" | "valueOf" | "toLocaleString"
type K6 = keyof number;

// typeof Symbol.toStringTag | "toString" | "toLocaleString" | "valueOf"
type K7 = keyof bigint;

// "valueOf"
type K8 = keyof boolean;

// nmber | typeof Symbol.iterator | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "loacaleCompare" | "match" | "replace" | "search" | "slice" | ... 36 more ... | "replaceAll"
type K9 = keyof string;

// tyepof Symbol.toPrimitive | typeof Symbol.toStringTag | "toString" | "valueOf" | "description"
type K10 = keyof symbol;

接口(interface)

接口(Interface)与类型别名(Type aliases)可以认为是同一概念的两种语法。我们如何理解这句话呢?我们可以类比熟悉的函数定义函数表达式来理解。接口和函数定义比较像,类型别名和函数表达式比较像。

import { Equal } from '@type-challenges/unils';
// 对象类型
type TPerson = {name: string; age: nmber}
interface IPerson {name: string; age: nmber}
type R1 = Equal<TPerson, IPerson>;// true

// 索引类型
type TDict = {[key: string]: string};
interface IDict {[key: string]: string};
type R2 = Equal<TDict, IDict>;// true

// 函数签名
type TFn = (x:number)=> string;
interface Ifn {
    (x:number): string
}
type R3 = Equal<TFn, Ifn>;// true

// 元组
type TTuple = [number, number];
interface ITuple extends Array<number> {
    0: number;
    1: number;
    length: 2;
}
type R4 = Equal<TTuple, ITuple>;// true

接口和类型别名的区别

  1. 类型别名更为通用,其右侧可以包含类型表达式(类型联合、类型交叉、条件类型), 但接口右侧只能是某种结构({...})。
  2. 接口间继承(extends)时TS会检查二者关系。但类型联合时TS会尽最大努力尝试,不会报错。
  3. 同一个作用域中的多个同名接口声明会被合并。而多个同名类型别名会报错。 image.png

类(class)

class 是ES2015引入的新特性。我们这里先看下如何用interface描述一个 class ?

import { Equal } from '@type-challenges/unils';
class Point {
    x: number = 0;
    y: number = 0;
    constructor(x:number, y:number){
        this.x = x;
        this.y = y;
    }
}

interface IPoint {
    prototype: {x:number, y:number};
    new(x:number, y:number): {x:number, y:number};
    // 定义构造器的语法:new(x: X, y: Y, ...):
}

type TPoint = {
    prototype: {x:number, y:number};
    new(x:number, y:number): {x:number, y:number};
}

type TPointProps = keyof typeof Point;// "prototype"
type R1 = Equal<IPoint, typeof Point>;// true
type R2 = Equal<TPoint, typeof Point>;// true
type R3 = Equal<IPoint, TPoint>;// true

class 本质上是一个函数,从上述代码可知:

  1. 作为构造器的函数,必须具有 prototype属性。并且prototype类型 和构造器返回值的类型相同。
  2. 和Point constructor具有相同的函 数签名和返回值。

总结

上面我们主要学习了 Typescript 的类型操作、接口和类三大进阶知识,相信大家应该对 Typescript 有了更进一步了解,下期我们继续加深难度,学习 Typescript 高级知识。