【发布时间】:2021-04-28 02:06:27
【问题描述】:
这是我的设置:
定义属性
interface Props<T, X extends any[], Y extends any[]> {
T?: T
x?: <D extends T>(d: D, ...args: X) => number | Date | string
y?: <D extends T>(d: D, ...args: Y) => number | Date | string
}
定义使用 Props 接口的组件
class Component<T, X extends any[], Y extends any[]> {
_props: Props<T, X, Y>
constructor(props:Props<T, X, Y>){
this._props = props
}
}
实例化组件(我希望组件从 props 中推断出泛型类型)
const comp = new Component({
T:{a:10, b:20},
x:(d, g:number)=> d.a
})
我面临的问题是当我使用 x(或 y)属性时,将打印以下错误
Type '<D extends { a: number; b: number; }>(d: D, g: number) => number' is not assignable to type '<D extends { a: number; b: number; }>(d: D, g: number) => string | number | Date'.
Types of parameters 'd' and 'd' are incompatible.
Type 'D' is not assignable to type 'D'. Two different types with this name exist, but they are unrelated.
'D' is assignable to the constraint of type 'D', but 'D' could be instantiated with a different subtype of constraint '{ a: number; b: number; }'.
Type '{ a: number; b: number; }' is not assignable to type 'D'.
'{ a: number; b: number; }' is assignable to the constraint of type 'D', but 'D' could be instantiated with a different subtype of constraint '{ a: number; b: number; }'.
这是Typescript Playground中的完整代码
我想要的是推断其余参数类型并在以后使用它,所以如果有人对如何克服这个问题有很大的帮助,请提供建议
【问题讨论】:
-
嗯,你能解释一下为什么你需要使用通用的
D吗?你在这里所做的和只接受T类型的参数的this code 有什么区别?如果这被证明是 TS 编译器中的错误或限制,则报告可能需要显示一个激发它的用例,而现在似乎没有理由让x或y成为泛型方法 -
无论如何,看起来this 可能是minimal reproducible example 的情况。我会看看我是否能找到关于这个的现有 GitHub 问题。
-
我在 Svelte 框架中使用此代码,并且需要使用泛型 D 来正确推断类型,而没有 D 泛型我会得到任何类型,
-
我对独立的用例更感兴趣。像
<T extends X>(x: T)=>void这样的函数类型没有理由是泛型的,因为它可以替换为(x: X)=>void。另一方面,像<T extends X>(x: T) => T或<T extends X>(x: T, cb: (x: T)=>void)=>void这样的函数类型或至少两次提到T的函数类型不能用非泛型版本替换而不会丢失精度。如果我提出 GitHub 问题,我可能会做类似this 之类的事情 -
这里的答案很可能是类型推断对你不起作用,你必须手动指定比你想要的更多的类型。
标签: typescript typescript-generics