【问题标题】:How can I enforce TypeScript to give an error on this code?如何强制 TypeScript 对此代码给出错误?
【发布时间】:2018-05-06 08:27:11
【问题描述】:

通常在 TypeScript 中我定义了非常复杂的类型,所以我从来没有遇到过这个问题,但我找不到一个简单的方法来解决它。

type first = number;
type second = number;

let f: first = 1;
let s: second = 2;

const func = (arg1: first, arg2: second) => { };

func(s, f);

我希望从这段代码中得到一个错误,因为我用“first”类型的第一个参数和“second”类型的第二个参数定义了函数,但是当我调用它时,我传递了两个反转类型的参数

【问题讨论】:

  • 您刚刚创建了number 的别名。这就是firstsecond 兼容的原因。
  • 我知道它们是兼容的,但如果我为月份和日期创建一个类型,它们都应该是数字,但我希望 TS 阻止或警告我将它们的位置作为参数切换。跨度>
  • 目前打字稿不支持名义打字。您可以标记或标记类型example
  • @AlekseyL。如果您将其写为答案,我将接受它,因为它看起来像我正在寻找的东西

标签: typescript custom-type


【解决方案1】:

目前打字稿不支持nominal typing。 作为一种解决方法,人们使用类型标记/品牌:

type First = number & { readonly _tag: unique symbol };
type Second = number & { readonly _tag: unique symbol };

let f = 1 as First;
let s = 2 as Second;

const func = (arg1: First, arg2: Second) => { };
func(s, f);  // Error: Types of property '_tag' are incompatible.

【讨论】:

  • 很好的答案!这是我在打字稿教程中没有提到的一个聪明的解决方法。提供名称“nominal typing”也确实帮助我搜索更多信息!
【解决方案2】:

TypeScript 不关心类型名称(或别名),只关心类型的形状。 firstsecond 这两种类型对于编译器来说都是同一个类型,不会报错。

事实上,由于结构类型,这段代码也可以工作:

interface I1 {
  name: string;
  age: number;
}

interface I2 {
  age: number;
  name: string;
}

var a1: I1;
var a2: I2;

function log(arg1: I1, arg2: I2): void {
  console.log(arg1, arg2);
}

log(a2, a1);

因为,I1I2 也是同一类型的别名(两个接口具有相同类型的相同属性)

【讨论】:

  • 因此,如果我为月份和日期创建一个类型,它们都应该是数字,那么 TS 就无法阻止或警告我将它们的位置转换为参数?
  • 好吧,您可以为此定义枚举,这样您就无法切换。在任何情况下,使用 TS 您可以获得智能感知,因此很容易检测到您将几天分配到几个月,反之亦然。您还可以将 Month 类型定义为 type Month = 1 | 2 | 3 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12。这样,您无法将数字 13 分配给 Month 类型的变量。但是,当两个数字都小于 12 时,这并不能防止错误。在这种情况下,枚举更好。
猜你喜欢
  • 1970-01-01
  • 2018-04-19
  • 1970-01-01
  • 1970-01-01
  • 2013-10-20
  • 2018-01-11
  • 2021-11-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多