繁体   English   中英

打字稿重载箭头功能不起作用

[英]Typescript overload arrow function is not working

(我正在使用严格的空检查)

我有以下箭头函数,具有重载类型:

    type INumberConverter = {
      (value: number): number;
      (value: null): null;
    };
    const decimalToPercent: INumberConverter = (value: number | null): number | null => {
      if (!value) {
        return null;
      }
      return value * 100;
    };

根据我对其他问题的理解( 在对类方法使用粗箭头语法时,我可以使用 TypeScript 重载吗? )这应该是有效的。 我总是收到以下错误:

TS2322: Type '(value: number | null) => number | null' is not assignable to type 'INumberConverter'.   Type 'number | null' is not assignable to type 'number'.     Type 'null' is not assignable to type 'number'

如果我定期编写此函数(使用function关键字):

    function decimalToPercent(value: null): null;
    function decimalToPercent(value: number): number;
    function decimalToPercent(value: number | null): number | null {
      if (!value) {
        return null;
      }
      return value * 100;
    }

它工作没有错误。

我需要使用箭头函数所以this不会改变,我需要这个重载所以打字稿知道decimalToPercent(1)不能为空。

为什么它不像我做的那样工作,我该如何解决?

重载签名和实现签名之间的兼容性规则比赋值要宽松得多。

在这种情况下,您尝试将可能返回null的函数分配给具有禁止返回 null ( (value: number): number; ) 的重载的函数。 编译器会正确地发现这个麻烦。 对于重载,由于签名和实现都是作为一个单元编写的,因此编译器假定“您知道自己在做什么”(正确与否)。

您可以通过多种方式解决它:

您可以使用类型断言,尽管您会丢失大多数类型的实现、签名兼容性检查:

type INumberConverter = {
  (value: number): number;
  (value: null): null;
};
const decimalToPercent = ((value: number | null): number | null => {
  if (!value) {
    return null;
  }
  return value * 100;
}) as INumberConverter;

您也可以使用常规function并像在旧的ES5时代一样捕获this ,尽管此解决方案意味着复制大量函数签名:

type INumberConverter = {
  (value: number): number;
  (value: null): null;
};

class X {
    decimalToPercent: INumberConverter;
    multiper = 100;
    constructor() {
        let self = this;
        function decimalToPercent(value: number): number;
        function decimalToPercent(value: null): null;
        function decimalToPercent(value: number | null): number | null {
            if (!value) {
                return null;
            }
            // use self
            return value * self.multiper;
        };
        this.decimalToPercent = decimalToPercent;
    }
}

或者可能最简单的解决方案是在构造函数中使用bind并将函数编写为常规方法:

class X {

    decimalToPercent(value: number): number;
    decimalToPercent(value: null): null;
    decimalToPercent(value: number | null): number | null {
        if (!value) {
            return null;
        }
        return value * this.multiper;
    };
    multiper = 100;
    constructor() {
        this.decimalToPercent = this.decimalToPercent.bind(this);
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM