我遇到的情况是,我有一系列通用项目(Item
),并且在项目本身内,我希望推断和具体的通用参数。
也就是说,我想要一组通用项目,但每个项目都可以有不同的通用类型,应该保留这一点。
type Item<T> = {
value: T;
fn: (value: T) => void;
}
function usesItem<T>(item: Item<T>) {
}
// This is fine - the value is inferred
usesItem({
value: 999,
fn: (value) => {
//value is inferred as number
}
})
第一种方法,声明一个Array<Item<unknown>
:
function usesItems1(items: Array<Item<unknown>>) {
}
usesItems1([{
value: 999,
fn: (value) => {
// value is unknown - we want it to be number
}
}
])
第二种方法:从函数中引入泛型:
function usesItems2<T>(items: Array<Item<T>>) {
}
// appears to work...
usesItems2([{
value: 999,
fn: (value) => {
// value is number
}
}
])
// ...but it doesn't really
usesItems2([{
value: 999,
fn: (value) => {
// value is number
}
}, {
// Type 'string' is not assignable to type 'number'.(2322)
value: "aaa",
fn: (value) => {
}
}
]);
第三种方法——使用infer
关键字,我尝试了几种方法:
type InferredItem1<T> = T extends Item<infer R> ? Item<R> : never;
function usesItems3(items: Array<InferredItem1<unknown>>) {
}
usesItems3([{
//Type 'number' is not assignable to type 'never'.(2322)
value: 999,
fn: (value) => {
}
}
]);
type InferredItem2<T extends Item<unknown>> = T extends Item<infer R> ? Item<R> : never;
function usesItems3b(items: Array<InferredItem2<Item<unknown>>>) {
}
usesItems3b([{
value: 999,
fn: (value) => {
// value is unknown
}
}
]);
TypeScript 游乐场
我怎样才能实现我想要的?
或者,如果这是不可能的,我猜想是对 Github 问题/类似问题的规范引用。