TypeScript 杂记二 《类型体操》
Posted 左手121
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了TypeScript 杂记二 《类型体操》相关的知识,希望对你有一定的参考价值。
TypeScript 杂记二 《类型体操》
前提
type A = keyof any
// ===
type A = string | number | symbol
// infer 表示待推断的类型,如下内置类型
type ReturnType<T> = T extends (...args: any[]) => infer P ? P : any
type B = ReturnType<(value: string) => string>
// ===
type B = string
type Func = () => void
type C = keyof Func
// ===
type C = never
class Class
type C = keyof Class
// ===
type C = never
Pick<T, K>
type _Pick<T, K extends keyof T> =
[P in K]: T[P]
Readonly
type _Readonly<T> =
readonly [P in keyof T]: T[P]
Partial
type _Partial<T> =
[P in keyof T]?: T[P]
Required
type _Required<T> =
[P in keyof T]-?: T[P]
Record<T, K>
type _Record<T extends keyof any, K> =
[P in T]: K
Exclude<T, K>
type _Exclude<T, K> = T extends K ? never : T
Extract<T, K>
type _Extract<T, K> = T extends K ? T : never
Omit<T, K>
type _Omit<T, K extends keyof any> = _Pick<T, _Exclude<keyof T, K>>
First
实现一个通用 First<T>
,它接受一个数组 T 并返回它的第一个元素的类型
type First<T extends any[]> = T extends [] ? never : T[0]
Last
实现一个通用 Last<T>
,它接受一个数组 T 并返回它的最后一个元素的类型
type First<T extends any[]> = T extends [...infer O, infer R] ? R : never
Readonly2<T, K>
实现一个通用的 Readonly2<T, K>
,K 指定应设置为 Readonly 的 T 的属性集。如果未提供 K,则应使所有属性都变为只读,就像普通的 Readonly一样
// 自己写的
type Readonly2<T, K extends keyof T = any> = K extends never
? Readonly<T>
:
readonly [P in K]: T[P]
&
[P in Exclude<keyof T, K>]: T[P]
// 别人的精简版
type Readonly2<T, K extends keyof T = keyof T> =
readonly [P in K]: T[P]
& Omit<T, K>
DeepReadonly
实现一个通用的 DeepReadonly<T>
,它将对象的每个参数及其子对象递归地设为只读
// 满足简单数据结构
type DeepReadonly<T> =
readonly [P in keyof T]: DeepReadonly<T[P]>
// 处理函数和类,原因查看前提的内容
type DeepReadonly<T> = keyof T extends never
? T
:
readonly [P in keyof T]: DeepReadonly<T[P]>
Trim
type trimed = Trim<' Hello World '> // expected to be 'Hello World'
// 处理左侧的空格和换行,infer 请查看前提
// 一个一个递归处理
type TrimL<T extends string> = T extends `$' ' | '\\t' | '\\n'$infer S`
? TrimL<S>
: T
// 同理处理右侧
type TrimR<T extends string> = T extends `$infer S$' ' | '\\t' | '\\n'`
? TrimR<S>
: T
type Trim<T extends string> = TrimL<TrimR<T>>
// 整合起来
type Trim<T extends string> = T extends `$' ' | '\\t' | '\\n'$infer L`
? Trim<L>
: T extends `$infer R$' ' | '\\t' | '\\n'`
? Trim<R>
: T
vue
实现类似 Vue 的类型支持的简化版本
const instance = SimpleVue(
data()
return
firstname: 'Type',
lastname: 'Challenges',
amount: 10,
,
computed:
fullname()
return this.firstname + ' ' + this.lastname
,
,
methods:
hi()
alert(this.fullname.toLowerCase())
,
,
)
type ComputedReturn<T> =
[K in keyof T]: T[K] extends () => infer R ? R : never
declare function SimpleVue<D, C, M>(options:
data?(this: ): D
computed?: C & ThisType<D & ComputedReturn<C> & M>
methods?: M & ThisType<D & ComputedReturn<C> & M>
): D & ComputedReturn<C> & M
以上是关于TypeScript 杂记二 《类型体操》的主要内容,如果未能解决你的问题,请参考以下文章