typescript基础知识整理

235 阅读4分钟

Typescript基础知识整理

TO 0107

interface 和 type

都是用来定义数据类型的,规范数据对象的

相同点

interface User {
    name: string
    age: number
    setAge(age: number) : void
}
type User  = {
    name: string
    age: number
    setAge(age: number): void
}

type User = (age:number) => void 
  • Implements

    class实现type和interface接口的方式都是一样的, 其中type不能实现联合类型的接口

interface Point {
  x: number;
  y: number;
}

class SomePoint implements Point {
  x = 1;
  y = 2;
}

type Point2 = {
  x: number;
  y: number;
};

class SomePoint2 implements Point2 {
  x = 1;
  y = 2;
}

type PartialPoint = { x: number; } | { y: number; };

// 这里不能实现一个type联合类型的接口
class SomePartialPoint implements PartialPoint {
  x = 1;
  y = 2;
}

不同点

  • type可以定义成 原始数据类型 & 联合类型 & 元组interface不可以
type Name = string // type 可设置原始类型

// 联合类型
type PointX = {
  x: number
}
type PointY = {
  y: number
}
type Point = PointX | PointY

// 组合成tuple
type tuple = [number, string]
let t: tuple = [1, '1']
  • 扩展语法不同

    • interface extends interface

    interface PartialPointX { x: number; }
    interface Point extends PartialPointX { y: number; }
    
    • Type alias extends type alias

    type PartialPointX = { x: number; };
    type Point = PartialPointX & { y: number; };
    
    • Interface extends type alias

    type PartialPointX = { x: number; };
    interface Point extends PartialPointX { y: number; }
    
    • Type alias extends interface
    interface PartialPointX { x: number; }
    type Point = PartialPointX & { y: number; };
    
  • interface 可以而 type 不行, 自动类型合并

// interface 自动merging
interface User { name: string }
interface User { age: number }

let u: User = {
    name: 'zz',
    age: 2
} // 参数必须都要有

extends

继承

interface Animal {
	type: string;
}

interface Dog extends Animal {
	run(): void;
}

let dog: Dog = {
  type: 'dog',
  run: () => {}
} 

范型约束

redux 里 dispatch 一个 action,必须包含 type属性

interface Dispatch<T extends { type: string }> {
  (action: T): T
}

条件类型

T extends U ? X : Y // 若T能够赋值给U,那么类型是X,否则为Y

值匹配

type Equal<T, U> = T extends U ? true : false

type ENum = Equal<1, 1> // true

type EStr = Equal<'abc', 'abc'> // true

类型匹配

type GetType<T> = T extends number ? number : string;

type Num = GetType<1>   // number;
type Str = GetType<'1'> // string;

嵌套类型匹配

type GetType<T> = T extends number ? 'number'
								: T extends string ? 'string'
								: T extends boolean ? 'boolean'
								: T extends Function ? 'function'
								: 'object'


type T0 = GetType<string>;  // "string"
type T1 = GetType<"a">;     // "string"
type T2 = GetType<true>;    // "boolean"
type T3 = GetType<() => void>;  // "function"
type T4 = GetType<string[]>;    // "object"

判断联合类型

type A = 'x'
type B = 'x' | 'y'
type Y = A extends B ? true : false; // true

推迟解析条件类型

分配律是指,将联合类型的联合项拆成单项,分别代入条件类型,然后将每个单项代入得到的结果再联合起来,得到最终的判断结果。

type B = 'x' | 'y'
// T 等于除匹配类型的额外所有类型(官方叫候选类型)
type Merge<T> = T extends 'a' ? B : T;
type Values = Merge<"a" | "b"> // "b" | "x" | "y"


// T 等于匹配的类型,然后加上 B 联合类型一起返回
type Merge2<T> = T extends 'a' ? T : B;
type Values = Merge<"a" | "b"> // "x" | "y" | "a"

过滤类型函数

type Diff<T, K> = T extends K ? never : T

type Values = Diff<"x" | "y" | "z", "x">;
// 得到 type Values = "y" | "z"

never & unknown & any & void

any 任意类型

void: 和any相反,表示无任何类型

unknown 未知类型。 类型是 any 类型对应的安全类型。

never 类型表示那些永不存在的值的类型。比如函数抛出错误,这个函数永远也不会有返回值

function throwNewError(err: string): never {
	throw new Error(err)
}

infer

可以在 extends 条件语句中使用 infer 关键字来声明一个待推断的类型变量。

infer 的作用是让 TypeScript 自己推断,并将推断的结果存储到一个类型变量中,infer 只能用于 extends 语句中。

  • 实现待推断类型
type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer U ? U : never;
  • 元组转联合类型
type Flatten<T> = T extends Array<infer U> ? U : never;

type T0 = [string, number]
type T1 = Flatten<T0> // string | number

keyof

类型映射为一个名称所组成的联合类型

type Point = {
  x: number;
  y: number;
}

type KPoint = keyof Point; // x | y
interface Person {
	name: string;
	age: number;
	address: string;
}

type XiaoWang = keyof Person; // name | age | address

typeof


const point = {
  a : 1,
  b: 'test'
}
type P = keyof typeof point; // type '"a" || "b"'

const coordinate: P = 'z' // Type '"z"' is not assignable to type '"a" | "b"'.

in

可以用作遍历枚举

type Person = 'name' | 'age' | 'address'
type PersonKey = {
  [p in Person]: string;
}

type PersonKey = {
  name: string;
  age: string;
  address: string;
}

Record

构造一个对象类型,实现定义一个对象的 keyvalue 类型

Record<T, U>

定义

type Record<K extends string | number | symbol, T > = {
	[p in K]: T
} 
interface CatInfo {
  age: number;
  breed: string;
}
 
type CatName = "miffy" | "boris" | "mordred";
 
const cats: Record<CatName, CatInfo> = {
  miffy: { age: 10, breed: "Persian" },
  boris: { age: 5, breed: "Maine Coon" },
  mordred: { age: 16, breed: "British Shorthair" },
};

Object && object && {} 区别

Object

  • Object 接口定义了 Object.prototype 原型对象上的属性
  • ObjectConstructor 接口定义了 Object 类的属性

任何值都基础类型、非基础类型都可以定义为Object

interface Object {
  constructor: Function;
  toString(): string;
  toLocaleString(): string;
  valueOf(): Object;
  hasOwnProperty(v: PropertyKey): boolean;
  isPrototypeOf(v: Object): boolean;
  propertyIsEnumerable(v: PropertyKey): boolean;
}
interface ObjectConstructor {
 /** Invocation via `new` */
 new(value?: any): Object;
 /** Invocation via function calls */
 (value?: any): any;
 readonly prototype: Object;
 getPrototypeOf(o: any): any;
 // ···
}
declare var Object: ObjectConstructor;

object

object 接口只能定义任何非基础类型的的值。

object 是一个宽泛的通用的非基本类型

{}

一个空对象。编译期没有任何成员对象。也可以赋值基础类型和非基础类型的值(不包括nullundefined)