TypeScript中基于needs约束compute类型的嵌套映射类型推断问题
问题:通过
needs约束同类型中compute的类型,泛型自动推断失效 我希望通过对象的needs成员,约束同一类型中compute成员的参数类型。单个场景的实现相对容易,但在创建这类声明的命名集合时,遇到了泛型自动推断失效的问题。
单个场景示例
class User { public name: string = '' public last: string = '' } extend({ needs: {last: true}, // 选择compute中可用的User成员 compute: (user) => user.name // user被约束为Pick<User, 'last'>,此处会触发TS错误 })
命名集合场景示例
extend({ lastName: { needs: {last: true}, compute: (user) => user.last }, myName: { needs: {name: true}, compute: (user) => user.name } })
我的实现尝试及问题
以下是我的实现代码,但TypeScript无法正确推断泛型(见最后failing声明):
type ComputedField<T, K extends keyof T, V> = { needs: Record<K, boolean> compute: (input: Pick<T, K>) => V } type Narrowed<P, O extends Needs<P>> = { [key in keyof O]: O[key] extends {needs: infer K} ? keyof K : never } type NarrowedComp<P, O> = { [key in keyof O]: O[key] extends keyof P ? ComputedField<P, O[key], any> : never } type Needs<P> = {[key: string]: {needs: Partial<Record<keyof P, boolean>>}} function extend<T extends Needs<User>>(input: NarrowedComp<User, Narrowed<User, T>>): T {return this} // 测试用例 const needExample = { fullName: { needs: { last: true } } } satisfies Needs<User> const test = { fullName: { needs: {last: true}, compute: (user) => user.name // 预期触发错误! } } satisfies NarrowedComp<User, Narrowed<User, typeof needExample>> const working = extend<typeof needExample>({ // 手动指定泛型时正常 fullName: { needs: {last: true}, compute: (user) => user.name // 预期触发错误! } }) const failing = extend({ // 自动推断泛型时失效 fullName: { needs: {last: true}, // 不应报错却提示缺失name compute: (user) => user.name // 预期报错却无提示 } }) // TypeScript将泛型推断为Needs<User>,而非typeof needExample
问题点
- 手动指定泛型参数时,TS能正确约束
compute的参数类型,错误使用会触发预期报错 - 自动推断泛型时,TS将泛型推断为
Needs<User>,导致约束失效:不该报错的地方报错,该报错的地方无提示
内容的提问来源于stack exchange,提问作者Tobias Diez
相关产品推荐
相关产品推荐

