我写了一些typescript代码,我不太确定为什么它不像我预期的那样工作。如果有人能告诉我我做错了什么,或者我应该使用什么其他方法,我将非常合适。
假设我有一个函数name
和data
的Definition
interface Definition<TName extends string, TData extends any> {
name: TName;
data: TData;
}
Definition
在某一时刻转变为Action
。Action
有一个名为method
的函数,payload
是第一个参数类型。
interface Action<TDefinition extends Definition<string, any>> {
name: TDefinition["name"];
method: (data: TDefinition["data"]) => void;
}
请记住,所有Definition
的联合元素都必须经过Changer
。
interface Changer<TDefinition extends Definition<string, any>> {
actions: Action<TDefinition>[];
}
interface Definition<TName extends string, TData extends any> {
name: TName;
data: TData;
}
interface Action<TDefinition extends Definition<string, any>> {
name: TDefinition["name"];
method: (data: TDefinition["data"]) => void;
}
interface Changer<TDefinition extends Definition<string, any>> {
actions: Action<TDefinition>[];
}
const set: Changer<Definition<"one", 1> | Definition<"two", 2>> = {
actions: [
{
name: "one",
method: (data) => data, // data type is equal to '1 | 2' I would expect it to be '1'
},
],
};
set.actions[0].method(1); // data type is equal to '1 | 2' I would expect it to be '1'
你能告诉我我该怎么做才能达到我期望的结果吗?
我正在考虑新的Definition
,但我相信我可能有一些问题,因为[key: string]: any
。
interface Definition<TName extends string, TData extends { [key: string]: any }> {
[key in TName]: TData[key]
}
你觉得怎么样?
这可以通过使用分配条件类型来解决。
interface Changer<TDefinition extends Definition<string, any>> {
actions: (
TDefinition extends infer U extends Definition<string, any>
? Action<U>
: never
)[];
}
我们基本上想改变actions
的类型,从
actions: Action<Definition<"one", 1> | Definition<"two", 2>>[]
转换为
类型actions: (Action<Definition<"one", 1>> | Action<Definition<"two", 2>>)[]
这可以通过强制TDefinition
的联合元素通过条件分布到单个Actions
来实现。
游乐场
现在我们有了函数中参数的正确类型。
const set: Changer<Definition<"one", 1> | Definition<"two", 2>> = {
actions: [
{
name: "one",
method: (data) => data, // data: 1
},
{
name: "two",
method: (data) => data // data: 2
}
],
};
但是这个语句不起作用:
set.actions[0].method(1); // Argument of type 'number' is not assignable to parameter of type 'never'
set
变量没有关于单个数组元素的信息,因为你给了它一个显式类型. 要解决这个问题,您可以使用泛型函数创建set
。