TS2322:无法将类型分配给带有箭头功能的类型

时间:2020-04-29 17:56:57

标签: typescript

我试图用箭头函数定义一个基本接口作为属性。但是,这给了我一个TS错误。

interface InterfaceTest {
  input?: (test: number | string) => number | undefined;
}

const myVariable: InterfaceTest = {
  input: (test: number) => {
    return test;
  },
};

const myVariable2: InterfaceTest = {
  input: (test: string) => {
    return parseInt(test, 2);
  },
};

TS2322:类型'(test:number)=> undefined'不能分配给类型'(test:string | number)=> number |未定义”。 参数“ test”和“ test”的类型不兼容。 输入'string |数字”不能分配给“数字”类型。 不能将“字符串”类型分配给“数字”类型。

实际上,我不理解该错误,因为我想将字符串或数字作为函数的参数,它告诉我不仅可以数字。如何将字符串或数字作为我的箭头函数的输入?

此外,当我这样做时,错误消失了

interface InterfaceTest {
  input?(test: number | string): number | undefined;
}

const myVariable: InterfaceTest = {
  input: (test: number) => {
    return test;
  },
};

const myVariable2: InterfaceTest = {
  input: (test: string) => {
    return parseInt(test, 2);
  },
};

为什么?

1 个答案:

答案 0 :(得分:2)

简单地说..如果接口说您可以传递字符串或数字,则在实现该接口时..该函数还需要能够接收字符串或数字。

如果接口的实现的类型从string | number减少到stringnumber,则会破坏合同。

所以不可能做我正在做的事情

很难说,因为您的示例是一个非常人为的示例,可能不代表您实际上正在尝试做的事情。

使用接口的想法是,其他接口可以接收该接口的实例,并放心它们可以使用字符串或数字来实现您的功能。显然,这不适用于您的情况,因为myVariable仅采用数字,而myVariable2仅采用字符串。

可以这样表达接口:

interface InterfaceTest {
   input?: (test: number) => number | undefined | (test: string) => number | undefined;
}

此接口指出,如果input存在,则必须实现这两个函数中的任何一个,但是使用该函数也会遇到麻烦,因为现在不容易确定是否存在接口的实现是numberstring类型。

这可能意味着类型保护或类型断言。

但是回到最初的观点,我认为这个例子有点荒谬。界面的目标是什么?为什么根本没有接口?

在什么情况下,您需要能够用myVariable代替myVariable2

剥离接口显然可行,因此使用该接口一定是有原因的:

const myVariable = {
  input: (test: number) => {
    return test;
  },
};

const myVariable2 = {
  input: (test: string) => {
    return parseInt(test, 2);
  },
};

有一种方法可以解决这种低谷的泛型,但是我很犹豫地提出这个建议,因为我担心您可能出于正确的原因未使用该接口。

但是这里是

假设您的InterfaceTest具有许多功能,并且可能具有input功能。但是InterfaceTest基本上有2个变体,有一个变体仅适用于数字,而有一个变体仅适用于字符串。

示例的通用版本如下所示:

interface InterfaceTest<T> {
  input?(test: T): number | undefined;
}

const myVariable: InterfaceTest<number> = {
  input: (test: number) => {
    return test;
  },
};

const myVariable2: InterfaceTest<string> = {
  input: (test: string) => {
    return parseInt(test, 2);
  },
};