TypeScript如何从已有的数据类型构造新的数据类型?

发布时间 2023-07-04 20:02:04作者: unuliha
1、对当前的对象类型增加属性——extends
interface Person {
    name:string;
    age:number;
}

interface Man extends Person {
    beardLength:number;
}
2、取两个对象类型所有的属性——交叉类型&
interface Person {
    name:string;
    age:number;
}

interface Student {
    id:string;
}

type Test = Person & Student;

let tom:Test = {
    name:'Tom',
    age:18,
    id:'111',
};
3、取两个对象类型中至少一个对象类型的所有属性——联合类型|

当期望变量是联合类型时,TypeScript会根据当前输入判断变量的类型:

interface Person {
    name:string;
    age:number;
}

interface Student {
    id:string;
}

type Test = Person | Student;

//类型 "{ age: number; }" 中缺少属性 "name",但类型 "Person" 中需要该属性。TypeScript根据输入的age,将该变量判断为了Person类型
let Tom:Test = {
    age:12, 
};

//TypeScript根据输入的id,将该变量判断为了Student类型
let Bob: Test = {
    id: '12',
};

//TypeScript根据输入的id,name,age,将John判断为了Person & Student
let John:Test = {
    name:'John',
    id:'123',
    age: 18,
}

注意:当TypeScript不确定一个联合类型的变量到底是哪种类型时,我们只能访问此联合类型的所有类型的公共属性和方法。

4、将当前对象类型的属性全部变为可选属性——Patial映射类型
interface Person {
    name:string;
    age:number;
    id:string;
}

// 报错 类型“{}”缺少类型“Person”中的以下属性: name, age, id
let John:Person = {};

type PartialPerson = Partial<Person>

// 不报错,因为所有属性变为了可选属性
let Tom: PartialPerson = {};
5、将当前对象类型的属性全部变为必填属性——Required映射类型
/**
 * Make all properties in T required
 */
type Required<T> = {
    [P in keyof T]-?: T[P];
};
6、将当前对象类型的属性全部变为只读——Readonly映射类型

使用方式同Partial,定义如下:

type Readonly<T> = {
    readonly [P in keyof T]: T[P];
}
7、从联合类型A | B中移除联合类型B中所有类型——Exclude映射类型
type T = Exclude<"a" | "b" | "c" | "d","a" | "c" | "f">; //"b" | "d"
8、从类型A中提取出可以分配给联合类型B的类型——Extract映射类型
type T = Extract<"a" | "b" | "c" | "d", "a" | "c" | "f">; //"a" | "c"
9、只保留当前对象类型中的某几个属性——Pick映射类型
interface Person {
    name:string;
    age:number;
    id:string;
}

// 只保留age和id属性
type PickPerson = Pick<Person, "age" | "id">
10、删除当前对象类型中的某些属性——Omit映射类型
interface Person {
    name:string;
    age:number;
    id:string;
}

type T = Omit<Person, "age">; //只保留name,id
11、快速构造对象类型的属性及值的类型——Record映射类型
type recordString = Record<string, any>
// 等价
type recordString = {
    [x: string]: any;
}

type recordReq = Record<"id" | "token" | "data", any>
// 等价
type recordReq = {
    id: any;
    token: any;
    data: any;
}
12、剔除掉联合类型中的nullundefined——NonNullable映射类型
type Msg = string | null | number | undefined;
type MsgNonNullable = NonNullable<reMsgsMsg>;
// 等价
type nonNullable = string | number;
13、获取函数类型中的传入的参数类型——Parameters映射类型
interface ShowInfo {
    (msg: string, type: number): string;
}
type parameters = Parameters<ShowInfo>;
// 结果
type parameters = [msg: string, type: number]
14、获取函数类型中的返回值的类型——ReturnType映射类型
interface ShowInfo {
    (msg: string, type: number): string;
}
type returnType = ReturnType<ShowInfo>;
// 结果
type returnType = string
15、获取类的构造函数的参数类型——ConstructorParameters映射类型
class Car{
  name:string
  color:string

  constructor(name: string, color:string){
    this.name = name
    this.color = color
  }

}

interface CarConstructor{
  new (name: string, color:string): Car
}

const args:ConstructorParameters<CarConstructor> = ['mini', 'blue']
// type ['string', 'string']

const c = new Car(...args)
16、获取类的实例的类型——InstanceType映射类型
class Car{
  name:string
  color:string

  constructor(name: string, color:string){
    this.name = name
    this.color = color
  }

}

interface CarConstructor{
  new (name: string, color:string): Car
}

type c = InstanceType<CarConstructor>
// type Car
17、将当前类型字符字面量全大写——Uppercase映射类型
type Status = 'success' | 'fail'
type STATUS = Uppercase<Status>
// type "SUCCESS" | "FAIL"
18、将当前类型字符字面量全小写——Lowercase映射类型
type Status = "SUCCESS" | "FAIL"
type status = Lowercase<Status>
// type "success" | "fail"
19、字符字面量首字母大写——Capitalize映射类型
type Status = "success" | "FAIL"
type status = Capitalize<Status>
// type "FAIL" | "Success"
20、字符字面量首字母小写——Uncapitalize映射类型
type Status = "success" | "FAIL"
type status = Uncapitalize<Status>
// type "success" | "fAIL"
参考: