在Typescript中,我有一个通用接口,表示要传递给函数的类型。
//foo must be an object {}, not a number or string or boolean or array
interface MyInterface<T extends {[key: string]: any}> {
foo: T
}
所以我使函数通用,但TS不能从我的界面中推断约束
const myGenericFn: <T, U extends MyInterface<T>>(bar: U) => void = (bar) => {
//Why is T not constrained to {[key: string]: any}?
//Shouldn't the constraint be inferred from MyInterface<T>?
// Or be an error since T doesn't extend {[key: string]: any}?
//bar.foo is T but T does not extend {[key: string]: any}!
const baz = bar.foo
}
//No error! Should be constrained to {foo: {[key: string]: any}} but accepts {foo: string}!
myGenericFn({foo: "bar"})
我能看到的唯一方法就是像这样重复对T的约束
const myGenericFnNotDRY: <T extends {[key: string]: any}, U extends MyInterface<T>>(bar: U) => void = (bar) => {
//Not DRY, I have to repeat my generic constraint everywhere I want to use MyInterface within a generic fn!
//bar.foo now correctly extends {[key: string]: any}
const baz = bar.foo
}
//Errors as expected, string not assignable to {[key: string]: any}
myGenericFnNotDRY({foo: "bar"})
这似乎是TS中的一个大漏洞-它在不告诉我的情况下默默地删除了类型约束。这很容易导致很难跟踪错误。我可能在这里缺少一些基本概念。
TS为什么不从MyInterface推断对T的约束?如何键入我的函数,以便将T正确地约束到MyInterface上特定的约束?