鉴于以下情况:
type Action =
| { type: 'FOO' }
| { type: 'BAR' }
type Rule = {
target: string | string[],
consequence: (action:Action) => void
}
const rule1:Rule = {
target: 'FOO',
consequence: action => console.log(action) // { type: 'FOO' }
}
const rule2:Rule = {
target: ['FOO', 'BAR'],
consequence: action => console.log(action) // { type: 'FOO' } | { type: 'BAR' }
}
可以分派动作(例如使用redux),规则可以对此作出反应。当目标匹配 action.type 时,结果将与匹配的动作一起执行。
我希望规则后果推断正确的类型。 目标可以通过某种方式完成此操作。但是我不知道如何。我目前的方法:
type Rule<Action> = {
target: string | string[],
consequence: (action:Action) => void
}
const rule:Rule<{ type: 'FOO' }> = ...
但是我需要一种可以写作的方式
const rule:Rule<{ type: 'FOO' } | { type: 'BAR' }> = ...
,根据规则 target
推断出正确的类型答案 0 :(得分:0)
这是我能找出的最好的方法。您将不得不放弃target
作为单个值,并且始终依赖于它是一个数组,即使该数组只有一个元素也是如此。可能有一种方法可以使其与函数重载一起使用,但我无法使其正常工作。
type ActionType = "FOO" | "BAR";
type Action<T extends ActionType> = { type: T };
function createRule<T extends ActionType[]>(target: T) {
return {
target,
consequence: (action: Action<T[number]>) => console.log(action)
};
}
const foo = createRule(["FOO"]);
const bar = createRule(["FOO", "BAR"]);
foo.consequence({ type: "FOO" });
foo.consequence({ type: "BAR" }); // nope
bar.consequence({ type: "FOO" });
bar.consequence({ type: "BAR" });
bar.consequence({ type: "BAZ" }); // nope
https://codesandbox.io/s/dawn-wildflower-03cbq?file=/src/index.ts
使用函数创建规则可以使您使用泛型,而不必在每次创建新规则时都将其同时指定为类型和值,从而无需重复进行操作。