//#region src/types/object.d.ts /** * 使用值类型过滤索引类型 * @public */ type FilterRecordByValue, ValueType> = { [Key in keyof Obj as Obj[Key] extends ValueType ? Key : never]: Obj[Key] }; /** * 提取Record中的可选索引 * 注意可选在ts里不等于值可能为undefined吗,虽然在js里是一样的 * 即\{age: number | undefined \} 和 \{ age?: number \} 不相等 * 可选表示可以没有这个索引 * @public */ type ExtractOptional> = { [Key in keyof Obj as Record extends Pick ? Key : never]: Obj[Key] }; /** * 判断Record的某个key是否为必选,也就是排除可选 * 可选的可以用Record\ ,也就是空的索引\{\} extends来判断 * @public */ type IsRequired> = Record extends Pick ? false : true; /** * 提取Record中的必选索引 * @public */ type ExtractRequired> = { [Key in keyof Obj as IsRequired extends true ? Key : never]: Obj[Key] }; /** * 移除索引签名 * 即 [key:string]:any * 这个允许任意key * * 这里利用了索引签名不能构造字面量类型(因为没有名字) * @public */ type RemoveIndexSignature> = { [Key in keyof Obj as Key extends `${infer Str}` ? Str : never]: Obj[Key] }; /** * ts的类型会在使用时才计算 * 这个拷贝触发类型计算,计算出最后的索引类型 * @public */ type CopyRecord> = { [Key in keyof Obj]: Obj[Key] }; /** * 执行Record的部分key为可选 * @public */ type PartialBy, Key extends keyof any> = CopyRecord>> & Omit>; /** * 获取Record的所有key的路径的联合类型 * @public */ type AllKeyPath> = { [Key in keyof Obj]: Key extends string ? Obj[Key] extends Record ? Key | `${Key}.${AllKeyPath}` : Key : never }[keyof Obj]; /** * 递归给对象字面量类型,添加Record\,即每一层可以额外添加任意字段 * @public */ type DeepRecord> = { [Key in keyof Obj]: Obj[Key] extends Record ? DeepRecord & Record : Obj[Key] } & Record; /** * 给对象字面量类型所有key添加前缀 * @public */ type PrefixKeyBy, Prefix extends string> = { [Key in keyof Obj as `${Prefix}${Key & string}`]: Obj[Key] }; //#endregion export { AllKeyPath, CopyRecord, DeepRecord, ExtractOptional, ExtractRequired, FilterRecordByValue, IsRequired, PartialBy, PrefixKeyBy, RemoveIndexSignature };