代码之家  ›  专栏  ›  技术社区  ›  Christian Ivicevic

typeof variable===“function”为true,但由于意外的类型合并,变量仍然缺少调用签名

  •  0
  • Christian Ivicevic  · 技术社区  · 7 年前

    export abstract class Room<State> {
        protected state: State;
    
        protected setState<Key extends keyof State>(
            state: ((previousState: Readonly<State>) => Pick<State, Key> | State)
                 | (Pick<State, Key> | State)
        ) {
            if (typeof state === "function") {
                // Cannot invoke an expression whose type lacks a call signature. Type
                // '((previousState: Readonly<State>) => State | Pick<State, Key>) | (State & Function)'
                // has no compatible call signatures.
                const newState = state(this.state);
                // ...
            }
            // ...
        }
        // ...
    }
    
    

    | State 最后 state 类型可以工作,但是在VS代码中,Intellisense不再在诸如 this.setState({ foo: 1 }); .

    第二种类型是为什么合并 State & Function ? 有可能安全地重写这个吗?

    1 回复  |  直到 7 年前
        1
  •  2
  •   Shanon Jackson    7 年前

    希望这有帮助,这里有一些事情正在进行,首先,额外的方括号没有任何作用,因为联合是交换的,意思是a |(B | C)和(a | B)| C基本上方括号没有任何意义,其次,要绕过函数问题,只需写状态类型!==“object”意味着你从联合中去掉了2/3,只剩下函数。希望这有帮助

    export abstract class Room<State extends object> {
        protected state: State = "" as any;
    
        protected setState<Key extends keyof State>(
            state: ((previousState: Readonly<State>) => Pick<State, Key> | State) | (Pick<State, Key>) | State
        ) {
            if (typeof state !== "object") {
                const newState = state(this.state);
            }
        }
    }
    

        2
  •  0
  •   hackape    7 年前

    您需要一个类型保护来帮助您将联合类型缩小到特定的函数类型。

    function isFunc(state: any): state is Function {
      return typeof state === "function"
    }
    
    // then replace 
    if (typeof state === "function") { ... }
    
    // with
    if (isFunc(state)) { ... }
    
    推荐文章