我正在尝试为模型的操作创建对象开关,但是在使用所有操作定义对象时,TS 抱怨传递的操作与找到的方法不匹配:
TS2345:PActions 类型的参数不可分配给 never 类型的参数
十字路口
ILine & ICurve & IStroke & IBegin & IMove & IClose
被减少为从不,因为财产手段在某些成分中具有冲突的类型。
ILine 类型不可分配给 never 类型
我知道它来自哪里:属性
means
定义了操作类型并且每个操作都是不同的,但我试图告诉编译器这是设计使然,他可以放心我已经处理了所有类型:
type Actions = {
[R in PActions["means"]]: (action: Extract<PActions, { means: R }>) => void
};
如果我将
action
定义为任意,则效果很好,但这很糟糕。
如果可能的话,我想定义它而不必求助于
any
类型,有人知道怎么做吗?
以下是实际实现:
type Actions = {
[R in PActions["means"]]: (action: Extract<PActions, { means: R }>) => void
};
interface ILine {
means: 'line';
args: ...
}
interface ICurve {
means: 'curve';
args: ...
}
...
export type PActions = ILine | ICurve | ...;
export function ResolveAction(
action: PActions,
): void {
const objSwitch: Actions = {
line: (action: ILine): void => ...,
curve: (action: ICurve): void => ...,
...
};
if (!action.means) {
(action as ILine).means = 'line'
}
if (!objSwitch[action.means]) {
return;
}
// Can't really figure out a way to tell ts that based on the property name object is properly selected, and he
// doesn't have to worry :<
objSwitch[action.means](action);
}
我还尝试定义公共父级并将其用作
action
类型,但它抱怨不匹配任何内容(毫不奇怪)。
其实在这种情况下
any
就等于“不用担心”,因为ts在这里做得很好,处理一些你知道没问题的事情,但是ts没有办法让它放心,所以解决方案是用 any
告诉 ts“让我来处理它”。
但是,一个可能的解决方案,但有点冗长是:
export function ResolveAction(action: PActions): void {
const objSwitch: Actions = {
line: (action: ILine): void => {},
curve: (action: ICurve): void => {},
};
if (!objSwitch[action.means]) {
return;
}
switch (action.means ? action.means : "line") {
case "line":
objSwitch.line(action as ILine);
break;
case "curve":
objSwitch.curve(action as ICurve);
break;
default:
break;
}
}