Typescript 笔记

288 阅读2分钟

TS 实现 Partial & Required & Readonly & Pick & Exclude & Extract & Omit

1. Partial 作用:生成一个新类型,该类型与 T 拥有相同的属性,但是所有属性皆为可选项

type IPartial<T> = {
    [key in keyof T]?:T[key]
}
interface Foo{
    name:string;
}
type Bar = IPartial<Foo>;
// 相当于
// type Bar = {
//     name?:string;
// }

2.Required 作用:生成一个新类型,该类型与 T 拥有相同的属性,但是所有属性皆为必选项

type IRequire<T> = {
    [P in keyof T]-?: T[P]
}
interface Foo2 {
    name: string
    age?: number
}
type Bar1 = Required<Foo2>
// 相当于 
// type Bar2 = {
//     name: string
//     age: string
// }

3.Readonly 作用:生成一个新类型,该类型与 T 拥有相同的属性,但是所有属性皆为必选项

type IReadonly<T> = {
   readonly [key in keyof T]-?:T[key]
}
interface Foo3 {
    name: string
    age: number
}
type Bar3 = IReadonly<Foo>
// 相当于 type Bar3 = { readonly name: string readonly age: string }

4.Pick 作用:生成一个新类型,该类型拥有 T 中的 K 属性

type IPick<T,K extends keyof T> = {
    [P in K]:T[P]
}
interface Foo4 {
    name: string
    age?: number
    gender: string
}
type Bar4 = IPick<Foo4, 'age' | 'gender'> // Pick<interface,key>
// 相当于 type Bar4 = { 
//    age?: string;
//    gender: string
   }

5. Exclude 作用:如果 T 是 U 的子类型则返回 never, 不是则返回 T, 求差集

type IExclude<T,U> = T extends U ? never : T;
interface Foo5 {
    name: string
    age?: number
    gender: string
}
interface Test {
    name:string;
}
type Bar5 = IExclude<'a'|'b'|'c', 'a'> // 'b'|'c'
type t1 = keyof Foo5;
type t2 = keyof Test;
type Bar6 = IExclude<t1, t2> // 'age'|'gender'

6.扩展 Diff,Filter

type Diff<T, U> = T extends U ? never : T; // 找出T的差集
type Filter<T, U> = T extends U ? T : never; // 找出交集

type T30 = Diff<"a" | "b" | "c" | "d", "a" | "c" | "f">;  // => "b" | "d"
// <"a" | "b" | "c" | "d", "a" | "c" | "f">
// 相当于
// <'a', "a" | "c" | "f"> |
// <'b', "a" | "c" | "f"> |
// <'c', "a" | "c" | "f"> |
// <'d', "a" | "c" | "f">
type T31 = Filter<"a" | "b" | "c" | "d", "a" | "c" | "f">;  // => "a" | "c"
// <"a" | "b" | "c" | "d", "a" | "c" | "f"> 同上

let demo1: Diff<number, string>; // => number

7.Extract 作用: 和 Exclude 相反, 求交集

// 6.扩展写 Include
type IInclude<T, U> = T extends U ? T : never;
type C1 = IInclude<'a'|'b'|'c','c'>

// 7.Extract 作用: 和 Exclude 相反, 求交集
type IExtract<T,U> = T extends U ? T : never;

type A1 = number | string | boolean;
type A2 = number | boolean;

type B1 = IExtract<A1,A2>;
// 相当于 type Foo = number | boolean

8.Omit 作用:生成一个新类型,该类型拥有 T 中除了 K 属性以外的所有属性

type IOmit<T,K extends keyof T> = IPick<T,IExclude<keyof T,K>>
interface Foo8 {
    name: string
    age: number
}
type Bar8 = IOmit<Foo8, 'age'>
// 相当于 type Bar = { name: string }

9.type和interface区别

* 相同点:
 * 1.都可以描述一个对象或者函数 
 * 2.都允许拓展(extends),虽然效果差不多,但是两者语法不同
* 不同点:
 * 1.type 可以声明基本类型别名,联合类型,元组等类型,interface不行;
 * 2.type 语句中还可以使用 typeof 获取实例的 类型进行赋值,interface不行;
 * 3.interface 能够声明合并,type不行
 type Name = {
    name: string;
}
//&符,type也可以extends扩展
type User = Name & { age: number };
let obj: User = {
    name: 'll',
    age: 12
}

// 当你想获取一个变量的类型时,使用 typeof
let div = document.createElement('div');
type B = typeof div

// 联合类型
type str = 'a' | 'b' | 'c';
let s:str = 'a'

// interface声明合并
interface Person {
    name: string
    age: number
}
interface Person {
    sex: string
}
type Hobby = {
    hobby:string;
}
// interface extends type
interface Person extends Hobby{}

let p:Person = {
    name:'mark',
    age:12,
    sex:'male',
    hobby:'旅游'
}