【问题标题】:Inconsistency in TypeScript function overloadTypeScript 函数重载不一致
【发布时间】:2021-11-20 16:01:42
【问题描述】:

考虑这个例子:

export function fn(arg: string): void;
export function fn(arg: number): void;
export function fn(arg: any) {
    console.log(arg);
}

所以,fn 可以用字符串或数字来调用。

fn('hello!');
fn(42);

到目前为止,一切都很好。 但随后fn 在不同的地方执行:

function fn2(arg2: string | number) {
    fn(arg2);
}

在这种情况下,TypeScript 会抱怨:

没有重载匹配这个调用。重载 1 of 2, '(arg: string): void',出现以下错误。

Argument of type 'string | number' is not assignable to parameter of type 'string'.
  Type 'number' is not assignable to type 'string'.   Overload 2 of 2, '(arg: number): void', gave the following error.
Argument of type 'string | number' is not assignable to parameter of type 'number'.
  Type 'string' is not assignable to type 'number'.ts(2769) 

index.tsx(3, 17): 调用会成功 实现,但重载的实现签名不是 外部可见。

有人可以帮我理解这里发生了什么吗?

【问题讨论】:

    标签: javascript typescript overloading typescript-typings


    【解决方案1】:

    您可以添加另一个重载

    export function fn(arg: string): void;
    export function fn(arg: number): void;
    export function fn(arg: any): void;
    export function fn(arg: any) {
        console.log(arg);
    }
    
    fn('hello!');
    fn(42);
    
    function fn2(arg2: string | number) {
        fn(arg2);
    }
    

    Playground

    【讨论】:

    • 这为我解决了这个问题,但我不知道为什么。你能解释一下为什么这会为我解决这个问题吗?
    • @ElliotLabsLLC 因为新的重载签名接受任何类型的参数。
    • 所以新的arg:any 参数反映了非重载函数参数,这些参数不计入 Transpiler 函数参数构造?
    • 它只涵盖anything,包括联合类型,在这种情况下为arg2: string | number
    • 因为没有为联合声明重载并且就打字稿而言,numberstring 可以分配给 number | string,但反之则不行
    【解决方案2】:

    重载与联合类型不同。重载定义了“单独的”函数,而联合则允许您将不同的类型作为参数。

    // fails
    function fn2(arg2: string | number) {
    
        fn(arg2); // uses the union type
    }
    
    // works 
    function fn3(arg2: string | number) {
        
        if(typeof arg2  === 'string') {
            return fn(arg2); // uses string
        }
        
        return fn(arg2); // uses number
    }
    
    

    这意味着fn2 搜索具有string|number 类型参数的函数声明,而fn3 搜索具有string 类型的函数或具有number 类型作为其第一个参数的函数。

    如果您确切知道要作为函数参数的类型,则不应使用any

    请参阅 documentation 了解联合类型

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-24
      • 2016-10-27
      • 2017-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多