根据参数进行类型推断
Type inference according to parameter
在下面的情况下,是否可以将result
的类型正确推断为boolean
?
interface ActionWithPayload<T extends string, K> { type: T, payload: K }
function ofType<T extends ActionWithPayload<string, any>>(...param: T["type"][]): T extends ActionWithPayload<typeof param[number], infer U> ? U : never {
return null;
}
enum one {
foo = "foo",
bar = "bar"
}
type action = ActionWithPayload<one.foo, boolean> | ActionWithPayload<one.bar, string>;
var result = ofType<action>(one.foo); // type of result should be boolean
问题是当 T
为 action
时 T["type"]
将是 one.foo | one.bar
,无论您传递什么参数。您需要一个额外的通用参数,以便编译器推断您传入的枚举成员的文字类型:
function ofType<T extends ActionWithPayload<string, any>, K extends one = one>(...param:K[]): T extends ActionWithPayload<K, infer U> ? U : never {
return null as any;
}
var result = ofType<action, one.foo>(one.foo); // will be boolean
缺点是您必须显式指定文字类型 one.foo
因为您不能只指定一个类型参数。作为替代方案,您可以使用双函数方法,这样您就可以为第一个函数指定类型参数,并让推理对第二个函数起作用:
function ofType<T extends ActionWithPayload<string, any>>() {
return function <K extends one = one>(...param:K[]) : T extends ActionWithPayload<K, infer U> ? U : never{
return null;
}
}
var result = ofType<action>()(one.foo); // will be boolean
在下面的情况下,是否可以将result
的类型正确推断为boolean
?
interface ActionWithPayload<T extends string, K> { type: T, payload: K }
function ofType<T extends ActionWithPayload<string, any>>(...param: T["type"][]): T extends ActionWithPayload<typeof param[number], infer U> ? U : never {
return null;
}
enum one {
foo = "foo",
bar = "bar"
}
type action = ActionWithPayload<one.foo, boolean> | ActionWithPayload<one.bar, string>;
var result = ofType<action>(one.foo); // type of result should be boolean
问题是当 T
为 action
时 T["type"]
将是 one.foo | one.bar
,无论您传递什么参数。您需要一个额外的通用参数,以便编译器推断您传入的枚举成员的文字类型:
function ofType<T extends ActionWithPayload<string, any>, K extends one = one>(...param:K[]): T extends ActionWithPayload<K, infer U> ? U : never {
return null as any;
}
var result = ofType<action, one.foo>(one.foo); // will be boolean
缺点是您必须显式指定文字类型 one.foo
因为您不能只指定一个类型参数。作为替代方案,您可以使用双函数方法,这样您就可以为第一个函数指定类型参数,并让推理对第二个函数起作用:
function ofType<T extends ActionWithPayload<string, any>>() {
return function <K extends one = one>(...param:K[]) : T extends ActionWithPayload<K, infer U> ? U : never{
return null;
}
}
var result = ofType<action>()(one.foo); // will be boolean