开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情
前言
这篇内容主要是本人学习TS的一些笔记整理,该篇后续会不断整理和更新,与大家相互学习,共同进步!如果有写得不准确的地方欢迎提出issue,本人在前端领域还需努力,虚心求教,欢迎大家指出!
一.TS内置类型实现方式
- T(Type) : 在定义泛型时通常用作第一个类型变量名称
- K(Key):表示对象中的键类型
- V(Value):表示对象中的值类型
- E(Element):表示元素类型
- P (Parameters) :参数
- U : 一个新的类型变量
Tips:如果大家对extends的含义了解的不够清楚可以看一下掘金的这篇文章juejin.cn/post/699873…
1. Pick<T, K>(实现从类型 T 中选择出属性 K,构造成一个新的类型)
type Pick<T, K extends keyof T> = { [ I in K]: T[I] }
interface Todo {
title: string
description: string
completed: boolean
}
type TodoPreview = MyPick<Todo, 'title' | 'completed'>
const todo: TodoPreview = {
title: 'hh',
completed: false,
}
2. Readonly<T>
type Readonly<T> = { readonly [K in keyof T]: T[K] }
interface Todo {
title: string
description: string
}
const todo: Readonly<Todo> ={
title: "Hey",
description: "foobar"
}
todo.title = "Hello" // Error: cannot reassign a readonly property
3. Exclude<T, U> (从联合类型T中排除U的类型成员,来构造一个新的类型)
type MyExclude<T, U> = T extends U ? never : T;
type Result = MyExclude<'a' | 'b' , 'a'> // 'b'
注释:
- type Result = ('a' extends 'a' ? never : 'a') | ('b' extends 'a' ? never : 'b')
- never是所有类型的子类型即结果为:type Result = never | 'b'= 'b'
4. Extract (Exclude<T, U> 取反)
type Extract<T, U> = T extends U ? T : never;
type A = Extract<'key1' | 'key2', 'key1'> // 'key1'
5. Omit<T, K>泛型(Pick<T, K>
取反)
type Omit<T, K extends keyof T> = { [P in keyof T as P extends K ? never : P]: T[P]; };
也可根据上方Exclude写成:
type Omit<T, K extends keyof T> = { [P in Exclude<keyof T, K>]: T[P]; }
精简版:
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
interface Todo {
title: string
description: string
completed: boolean
}
type TodoPreview = Omit<Todo, 'description' | 'title'>
const todo: TodoPreview = {
completed: false,
}
// 注释: P 是 Todo类型中的键值,as来类型断言为 P 是否为'description' | 'title' 的子类,如果是则为[never]:T[P]
// 即: 取其不是该子类的键值 => [P] : Todo[P]
6. Awaited(Promise<T>中 T 来描述这个 Promise 返回的类型)
type Awaited<T> = T extends PromiseLike< infer U> ? U extends PromiseLike<any> ? Awaited<U>: U : never;
精简版:
type Awaited<T> = T extends PromiseLike< infer U> ? Awaited<U> : T;
type ExampleType = Promise<string>
type Result = Awaited<ExampleType> // string
//注释:ExampleType继承PromiseLike下的表示待推断的新类型U ,
//string ? Awaited<string> :string,满足该条件返回该类型
7.Parameters(从一个函数类型Type的参数中使用的类型构建一个元组类型)
type Parameters<Function extends (...args: any) => any> = Function extends (...args: infer P) => any ? P : never;
const foo = (arg1: string, arg2: number): void => {}
type FunctionParamsType = Parameters<typeof foo> // [arg1: string, arg2: number]
二.实战演练笔记
1.获取元组长度
type Length<T extends readonly any[]> = T['length']
type tesla = ['tesla', 'model 3', 'model X', 'model Y']
type teslaLength = Length<tesla> // expected 4
2.实现元组转换为对象
type TupleToObject = { [Key in keyof T]: T[Key]};
注释:
-
keyof T用于从对象类型T中获取键值 key;
-
in用于对对象键值key进行迭代;
-
Key 就是对象键值 key 本身;
-
T[Key]是指定 Key 的值;]
type TupleToObject<T extends readonly any[]>={ [V in T[number]] : V }
注释:
- T[number] 用于从元组 T 中获取值;
- in 用于迭代元组值;
- Value 是元组元素,用作构建对象的key和value。
const tuple = ['tesla', 'model 3', 'model X', 'model Y'] as const
type result = TupleToObject<typeof tuple>
// { tesla: 'tesla', 'model 3': 'model 3', 'model X': 'model X', 'model Y': 'model Y'}
3.实现接受一个数组T并返回它的第一个元素的类型。
type First<T extends any[]>=T extends [] ? never : T[0]
type content=First<[1,2,3]> //返回元素1类型
4.实现一个 IF 类型,它接收一个条件类型 C ,一个判断为真时的返回类型 T ,以及一个判断为假时的返回类型 F。 C 只能是 true 或者 false, T 和 F 可以是任意类型。
type IF<C extends boolean,T,F>=C extends boolean ? T :F
type A = If<true, 'a', 'b'> // expected to be 'a'
type B = If<false, 'a', 'b'> // expected to be 'b'
5. 实现 JavaScript 内置的 Array.concat
方法
type Concat<T extends any[], U extends any[]> = [...T, ...U]
type Result = Concat<[1], [2]> // expected to be [1, 2]
总结
未完待续.....