You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// 返回对象 key 的常量联合类型 keyofT// hello | world // 返回对象值的联合类型 T[keyofT]// string | number T['hello']// string T['world']// number // in 操作符遍历联合类型 interfaceA{[Kinstring|number]: never[Kin'hello'|'world']: never[KinkeyofT]: T[K]}// ------ 源码 ------ /** * Make all properties in T required */typeRequired<T>={[PinkeyofT]-?: T[P];};/** * From T, pick a set of properties whose keys are in the union K */typePick<T,KextendskeyofT>={[PinK]: T[P];};/** * Construct a type with a set of properties K of type T */typeRecord<Kextendskeyofany,T>={[PinK]: T;}
// 条件类型推断 typeExample<T>=Textends infer R ? R : nevertypeA=Example<"1">// '1' typeB=Example<2>// 2
模式匹配
typeA=[1,2,3]typeExampleA=Aextends[infer First, ...infer Rest] ? First : never// 1 typeB="123"typeExampleB=Bextends `${infer FirstChar}${infer Rest}` ? FirstChar : never// '1' typeC=(p: number)=>stringtypeExampleB=Cextends(p: infer R)=>any ? R : never// number // ------ 源码(删减了类型约束) ------ /** * Obtain the parameters of a function type in a tuple */typeParameters<T>=Textends(...args: infer P)=>any ? P : never/** * Obtain the return type of a function type */typeReturnType<T>=Textends(...args: any)=> infer R ? R : any/** * Obtain the parameters of a constructor function type in a tuple */typeConstructorParameters<T>=Textendsabstractnew(...args: infer P)=>any
? P
: never/** * Obtain the return type of a constructor function type */typeInstanceType<T>=Textendsabstractnew(...args: any)=> infer R
? R
: any
// @ts-nocheck // Define a service using a base URL and expected endpoints exportconstpokemonApi=createApi({endpoints: (builder)=>({getPokemonByName: builder.query<Pokemon[],string>({query: (name)=>`pokemon/${name}`,}),getPokemonById: builder.query<Pokemon,string>({query: (id)=>`pokemon/${id}`,}),}),})// Export hooks for usage in functional components, which are // auto-generated based on the defined endpoints exportconst{ useGetPokemonByNameQuery, useGetPokemonByIdQuery }=pokemonApiconst{ data, isLoading, isError }=useGetPokemonByNameQuery()
/** * Convert string literal type to uppercase */typeUppercase<Sextendsstring>=intrinsic/** * Convert string literal type to lowercase */typeLowercase<Sextendsstring>=intrinsic/** * Convert first character of string literal type to uppercase */typeCapitalize<Sextendsstring>=intrinsic/** * Convert first character of string literal type to lowercase */typeUncapitalize<Sextendsstring>=intrinsic
2023-02-03
现如今 TS 已经完全走进了前端社区,纵观流行的前端框架/库,都有 TS 类型支持,不少框架/库更是对于源码是使用 TypeScript 开发,完美支持 TypeScript 类型提示当作一大亮点去宣传。
在业务中用 TS 写写页面、表格等上层逻辑,基本就是把后端数据定义/转换成 interface,往后一把梭就完了,不需要对 TS 的类型系统有深入的了解。
但当封装公用组件/函数时,如果想封装的代码能够支持 TS 类型,就需要了解类型编程的一些技巧,本文就分享一些常用的类型编程技巧。
好的 TS 类型支持
良好的类型推断,避免重复的类型定义
常见套路:提取 → 转换 → 重组 → 递归(循环)
前置知识
基础知识
对象操作:keyof、in
类型约束、条件类型:extends
条件类型推断:infer
模式匹配
函数参数泛型推导
示例
Get
Infer 在字符串模板中的小细节
RTK Query
Api 设计
实现
Redux
Api 设计
实现:略
TransformKeys
TransformMoney
扩展知识
字符串类型处理
联合类型转交叉类型
函数参数逆变 + 分配条件类型
逆变、协变
类型系统中的概念,表达父子类型关系
TS 中参数位置是逆变的,返回值是协变的
sl1673495/blogs#54
https://jkchao.github.io/typescript-book-chinese/tips/covarianceAndContravariance.html
元祖转联合
类型体操
T extends string ? T : never
TypeScript 类型体操天花板,用类型运算写一个 Lisp 解释器
用 TypeScript 类型运算实现一个中国象棋程序
Type Challenges
The text was updated successfully, but these errors were encountered: