与对象或函数的联合类型未正确检查函数签名

时间:2018-10-08 19:38:00

标签: typescript

当我定义了TransitionDefinition接口时,为什么没有得到编译器错误:

export interface State {
  name: string
}

export type StateResolveFunc = (fsm: string) => State[]

export interface TransitionDefinition {
  from: State | State[] | StateResolveFunc
}

,然后创建一个像这样的对象:

const t0: TransitionDefinition = {
  from: (fsm) => 'startState' // Why do I not get a compiler error?
}

我不应该在这里返回字符串! 当我只有函数类型而不是联合时,编译器会按预期抱怨。

Typescript example 使用打字稿3.1.1

1 个答案:

答案 0 :(得分:3)

因此,此行为背后的原因是所有函数都具有name属性。因此, any 函数将可分配给State

由于您可能不希望将任何可调用的内容分配给State,因此可以通过包含类型为apply的可选never字段来确保函数不可分配。像这样:

interface State {
  name: string;
  apply?: never; // Ensures functions are not assignable to this interface.
}

之所以可行,是因为所有函数都具有apply方法,但是该方法的类型不是never,这意味着无法将其分配给State。可以将相同的技巧与callbindapply之类的任何常用函数属性一起使用。

无论如何,使用该技巧,您的摘录:

export interface State {
  name: string;
  apply?: never;
}

export type StateResolveFunc = (fsm: string) => State[]

export interface TransitionDefinition {
  from: State | State[] | StateResolveFunc
}

const t0: TransitionDefinition = {
  from: (fsm) => 'startState' // Now produces an error
}

现在创建一个错误:

  

类型'string'不能分配给类型'State []'。