在单一类型参数

时间:2015-12-07 22:33:55

标签: typescript typescript1.7

在TypeScript中给出以下Code

const compareFn = {
    numberAsc: function (a: number, b: number) { return a - b },
    numberDesc: function (a: number, b: number) { return b - a },
};

[2, 1, "nope"].sort(compareFn.numberDesc);

enter image description here

我的函数numberDesc仅接受number类型的属性。但是,sort会同时适用numberstring。这是错误的,但被TypeScript接受。

我的猜测是,TypeScript期望sort()函数是一个接受数字或字符串的compareFn,但不是两者都严格。但是在我看来,它应该只允许一个接受数字和字符串的函数。

这是" Bug"或者TypeScript打算这样做?
但最重要的是:我可以让它发挥作用吗?给定一个数组应该只接受兼容的排序函数。

请注意,它在这里正常工作: enter image description here

3 个答案:

答案 0 :(得分:2)

这就是你所拥有的:

type Foo = (a:number,b:number)=>number;
type Bar = (a:number|string,b:number|string)=>number|string;

let foo:Foo;
let bar:Bar;
bar = foo; // Why is this valid!

有效,因为以下内容有效

let x:number;
let y:number|string;
y = x; // Valid for obvious reasons

在检查功能兼容性时,会在双向中检查参数兼容性。

有关此内容的更多信息:https://github.com/Microsoft/TypeScript-Handbook/blob/master/pages/Type%20Compatibility.md#comparing-two-functions

  

这是" Bug"或者TypeScript打算这样做?

意图表现得像那样。

  

但最重要的是:我可以让它发挥作用吗?给定一个数组应该只接受兼容的排序函数。

没有。正如所解释的,TypeScript中 compatible 函数的语义允许双变量。

答案 1 :(得分:0)

我不理解我理解你的问题,但我希望这会有所帮助。您需要阵列只接受数字。你的函数返回一个数字,所以没问题。

const compareFn = {
    numberAsc: function (a: number, b: number) { return a - b },
    numberDesc: function (a: number, b: number) { return b - a },
};

console.log([2, 1, "nope"].sort(compareFn.numberDesc));
console.log([2, 1, "nope"].sort(compareFn.numberAsc));
var numberArray = new Array<number>();
numberArray.push(2, 1);
numberArray.push(3, 4, "nope"); // kaboom
console.log(numberArray.sort(compareFn.numberDesc));
console.log(numberArray.sort(compareFn.numberAsc));
numberArray.push("nope"); // kaboom

当然,生成的JavaScript没有任何问题,但tsc会抱怨。

答案 2 :(得分:0)

请让我在这里解释我的答案,尽管巴拉干已经给了一个完美的答案。可能有助于某人更清楚地了解事情。

TypeScript的类型检查系统不是声音系统,这意味着它允许在编译时不可操作的操作。你的例子是这样的。 数组文字的类型推断使得TypeScript期望具有此签名的比较函数

{
 User:{
  'Name':"asdas",
  'Address_Line_1':"dasdasd"
  }
}

这是我所期望的,因为你的数组是

类型

(a: number | string, b: number | string) => number

因此,我想重新提一下你的问题“这是一个错误吗?” “为什么numberDesc被认为与此签名兼容?”

巴斯拉特已经给出了答案。

来自Java背景,我可以理解你希望在Java中进行更严格的类型检查,但我想你无法在这里得到它。