【问题标题】:is return-type signature in function overloading useless?函数重载中的返回类型签名没用吗?
【发布时间】:2014-11-03 22:24:03
【问题描述】:

Typescript 中的函数重载有意外行为。

看看函数重载example,返回值签名是函数重载的一部分。但是,返回类型似乎被完全忽略了。 Typescript 没有必要“选择”正确的函数参数签名,最困扰我的是,它不用于检查正确的返回值。

如果card的返回值从数字变为字符串,Typescript不会给出任何警告。

function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x): any {
  // Check to see if we're working with an object/array
  // if so, they gave us the deck and we'll pick the card
  if (typeof x == "object") {
    var pickedCard = Math.floor(Math.random() * x.length);
    return pickedCard;
  }
  // Otherwise just let them pick the card
  else if (typeof x == "number") {
    var pickedSuit = Math.floor(x / 13);
    return { suit: suits[pickedSuit], card: x % 13 }; // <-- change to card: '13'
  }
}

我的问题是:我是否正确解释了重载机制,那么提供返回值签名是不是必要的,或者这是一个错误?

【问题讨论】:

  • 是否至少在调用方进行了检查? (如果你调用第一个重载,当你将结果视为数字以外的东西时它会发出嘶哑的声音吗?)
  • 当使用 '15'(字符串)而不是 15(数字)调用 pickcard 时,它确实会抱怨。如果 return pickedCard 更改为 return 'someString' 它不会抱怨。
  • 不,我的意思是,调用方是否会根据选择正确的重载对返回值进行正确的类型推断?根据@SteveFenton 的回答,确实如此。所以你有一些价值,即使它没有完全检查函数的实现,它也会检查调用代码。
  • 是的,@SteveFenton 的回答显示了正确的行为,我现在有点明白 Typescript 正在检查类型而不是值。
  • 我确实得到了你想要的。在一个完美的世界中,它还应该检查实现的返回值以匹配这里使用的重载。事实上,没有必要拥有整个if (typeof) 东西,它应该进入单独的重载。毕竟,您的实现可能会忘记一种情况。但这可能要求太多......

标签: typescript


【解决方案1】:

当我调用你的函数时,我会返回以下类型:

// a is number
var a = pickCard([{ suit: 'hearts', card: 1 }]);

// b is {suit: string; card: number; }
var b = pickCard(1);

这让我不必手动指定它:

// a is number
var a: number = pickCard([{ suit: 'hearts', card: 1 }]);

// b is {suit: string; card: number; }
var b: {suit: string; card: number; } = pickCard(1);

如果您“以错误的方式”获取它们,您确实会收到有关类型的错误:

// a is number
var a: {suit: string; card: number; } = pickCard([{ suit: 'hearts', card: 1 }]);

// b is {suit: string; card: number; }
var b: number = pickCard(1);

因此,重载确实是根据您传递的参数来选择的 - 并且返回类型会根据所选重载进行调整。

View this example on the TypeScript Playground.

【讨论】:

  • 如果 pickCard 返回的不是数字而是字符串(例如由于编程错误),Typescript 不会抱怨。 (例如,请参阅gist.github.com/donnut/7a99207254d23de08ecb)。 a 将是 notANumber 而不是 2。
  • @甜甜圈。但这将是函数实现中的编程错误。您确实可以对调用该函数的代码进行类型检查。至少是这样。
  • 你是对的。忘记 Typescript 进行编译时类型检查而不是运行时是我的愚蠢。如果这样的编程错误也能被捕获,那就太好了。
  • 重载的问题是 TypeScript 只会根据实现签名检查返回类型(在提供的示例中是 any)。实现签名需要具有与所有指定返回类型兼容的返回类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-16
  • 2022-01-13
  • 2013-07-29
  • 2019-05-04
  • 1970-01-01
  • 2014-09-06
相关资源
最近更新 更多