void和never和any区别?

any:任意类型;
void: 表示没有任何类型,常用于函数的返回值类型 () => void;
never: 永远不存在的类型,比如 throw new Error('wrong'),或者根本没有返回值时;

泛型是什么?

定义:允许在程序中定义形式类型参数,然后在泛型实例化时使用实际类型参数来替换形式类型参数。
作用:实现组件复用

  1. function identity<T>(arg: T): T {
  2. return arg;
  3. }
  4. const foo = identity<string>('222'); // 也可以这样: const foo = identity('222'); 能够自动推断出字符串类型
  5. const foo = identity<number>(222);

type和interface的区别

  1. type能够用来表示非对象类型,而接口则只能表示对象类型;
  2. interface可以继承其他的接口、类,而type则不支持继承。type要实现类似继承的功能,可以借助交叉类型。 ```typescript interface Shape { name: string; } interface Circle extends Shape { radius: number; }

type Shape = {name: string};

type Circle = Shape & {radius: number};

  1. 3. interface具有**声明合并**的行为,而类型别名则不会进行声明合并。
  2. ```typescript
  3. interface A {
  4. x: number;
  5. }
  6. interface A {
  7. y: number;
  8. }
  9. // 相当于
  10. interface A {
  11. x: number;
  12. y: number;
  13. }

交叉类型和联合类型

交叉类型:表示一个值同属于多个类型,用“&”来表示;

  1. interface Clickable {
  2. click(): void;
  3. }
  4. interface Focusable {
  5. focus(): void;
  6. }
  7. type T = Clickable & Focusable;
  1. interface Clickable {
  2. register(x: any): void;
  3. }
  4. interface Focusable {
  5. register(x: string): boolean;
  6. }
  7. type ClickableAndFocusable = Clickable & Focusable;
  8. type FocusableAndFocusable = Focusable & Clickable;
  9. function foo(
  10. clickFocus: ClickableAndFocusable,
  11. focusClick: FocusableAndFocusable,
  12. ) {
  13. // 当交叉类型碰到函数重载时,与成员定义顺序一样,即使用了Clickable
  14. let a: void = clickFocus.register('foo');
  15. // 使用了 Focusable
  16. let b: boolean = focusClick.register('foo');
  17. }

联合类型:表示一个值的类型为多种类型之一,用“|”来表示;

交叉类型和联合类型的优先级:
当表示交叉类型的“&”符号与表示联合类型的“|”符号同时使用时,“&”符号具有更高的优先级。“&”符号如同数学中的乘法符号“×”,而“|”符号则如同数学中的加法符号“+”。

  1. A & B | C & D // 相当于(A & B) | (C & D)
  2. () => bigint | number // 相当于 () =>(bigint | number)

协变、逆变、双变

协变:设有两个复杂类型Complex(A)和Complex(B),如果由A是B的子类型能够得出Complex(A)是Complex(B)的子类型,那么我们将这种变型称作协变。A <: B → Complex(A) <: Complex(B)

  1. interface Animal {
  2. age: number;
  3. }
  4. interface Dog extends Animal {
  5. bark(): void;
  6. }
  7. let animal: Animal = { age: 12 };
  8. let dog: Dog = {
  9. age: 12,
  10. bark: () => {
  11. console.log('bark');
  12. },
  13. };
  14. animal = dog; // 兼容,能赋值成功,这就是一个协变
  15. dog = animal; // 不兼容,会抛出类型错误:Property 'bark' is missing in type 'Animal' but required in type 'Dog'

逆变:如果由A是B的子类型能够得出Complex(B)是Complex(A)的子类型,那么我们将这种变型称作逆变。A <: B → Complex(B) <: Complex(A)

  1. interface Animal {
  2. age: number;
  3. }
  4. interface Dog extends Animal {
  5. bark(): void;
  6. }
  7. let visitAnimal = (animal: Animal): Dog => {
  8. animal.age;
  9. return {
  10. age: 12,
  11. bark() {},
  12. };
  13. };
  14. let visitDog = (dog: Dog): Animal => {
  15. dog.age;
  16. dog.bark();
  17. return {
  18. age: 20,
  19. };
  20. };
  21. visitDog = visitAnimal; // 兼容
  22. visitAnimal = visitDog; // 不兼容, 会抛出类型错误

双变:如果由A是B的子类型或者B是A的子类型能够得出Complex(A)是Complex(B)的子类型,那么我们将这种变型称作双变。A <: B 或 B <: A → Complex(A) <: Complex(B)

函数重载

  1. function add(x: number, y: number): number;
  2. function add(x: any[], y: any[]): any[];
  3. function add(x: number | any[], y: number | any[]): any {
  4. // 省略了实现代码
  5. }