打字稿重载箭头功能不起作用 [英] Typescript overload arrow function is not working

查看:62
本文介绍了打字稿重载箭头功能不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

(我使用严格的空检查)

(I'm using strict null checks)

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

I have the following arrow function, with overloaded type:

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

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

To my understanding from other questions (Can I use TypeScript overloads when using fat arrow syntax for class methods?) this should be a valid. Never the less I get the following error:

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关键字):

If I write this function regularly (with the function keyword):

    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) 不能为空.

I need to use arrow function so this will not be change, and I need this overloading so typescript knows decimalToPercent(1) cannot be null.

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

Why doesn't it work the way I did it, and how can I fix it?

推荐答案

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

Rules for compatibility between overload signatures and implementation signature are much more relaxed than they are for assignment.

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

In this case you are trying to assign a function that may return null to a function that has an overload that forbids the returning of null ((value: number): number;). The compiler will rightly find this troubling. For overloads, since the signatures and the implementation are all written as one unit the compiler assumes 'You know what you are doing' (rightly or not).

您可以通过多种方式解决此问题:

You can work around it in several ways:

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

You can use a type assertion, although you will loose most type checking for implementation, signature compatibility:

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 并捕获 this 就像在旧的 ES5 时代一样,尽管这种解决方案意味着重复很多函数签名:

You could also use a regular function and capture this as in the old ES5 days, although this solution means duplicating a lot of the function signature:

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 并将函数编写为常规方法:

Or possibly the simplest solution is to use bind in the constructor and write the function as a regular method:

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);
    }
}

这篇关于打字稿重载箭头功能不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆