TypeScript如何无需satisfies关键字仅保留true字段类型?
问题原因与解决方案
你的问题核心在于手动类型标注导致TypeScript丢失了对象的具体类型信息:
当你给fields变量标注Fields类型时,TypeScript会把对象的具体键名(trueField、falseField)和布尔字面量类型(true/false)全部“抹平”成索引签名定义的{[string]: boolean}。此时typeof fields等价于Fields类型,而非包含具体键值对的结构化类型,这就导致GetTrues工具类型无法区分哪些字段的值是true,最终返回空类型。
解决方案一:省略手动类型标注,让TS自动推断
直接去掉Fields类型标注,TypeScript会自动保留对象的具体键名和字面量类型:
type GetTrues<T> = { [K in keyof T as T[K] extends true ? K : never]: T[K] } const fields = { trueField: true, falseField: false }; type myTrueFields = GetTrues<typeof fields> // 得到预期的 {trueField: true}
解决方案二:用satisfies约束类型同时保留细节
如果需要确保变量符合Fields类型约束,又不想丢失具体类型信息,satisfies是最优选择:
type Fields = { [FieldName: string]: boolean, } type GetTrues<T> = { [K in keyof T as T[K] extends true ? K : never]: T[K] } const fields = { trueField: true, falseField: false } satisfies Fields; type myTrueFields = GetTrues<typeof fields> // {trueField: true}
解决方案三:通过泛型函数约束类型
在satisfies关键字出现前,常用泛型函数实现“约束类型+保留具体信息”的需求:
type Fields = { [FieldName: string]: boolean, } type GetTrues<T> = { [K in keyof T as T[K] extends true ? K : never]: T[K] } function createFields<T extends Fields>(fields: T) { return fields; } const fields = createFields({ trueField: true, falseField: false }); type myTrueFields = GetTrues<typeof fields> // {trueField: true}
内容的提问来源于stack exchange,提问作者feissn
相关产品推荐
相关产品推荐

