

聊聊项目中常见的TypeScript错误
source link: https://www.fly63.com/article/detial/11273
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

扫一扫分享
TypeScript 错误信息由错误码和详细信息组成。例如:TS2456 ,其中错误码是以“TS”开头 + 数字(一般是 4 位数字)结尾这样的格式组成的字符串,用来作为特定类型错误的专属代号。下面我们看一下那些常⻅,但在官方文档甚少提及的类型错误:
1.TS2456
首先是由于类型别名循环引用了自身造成的 TS2456 类型错误,如下示例:
type T = Readonly<T>;
// TS2456: Type alias 'T' circularly references itself.
在上面这个例子中,对于 T 这个类型别名,如果 TypeScript 编译器想知道 T 类型是什么,就需要展开类型别名赋值的 Readonly 。而为了确定 Readonly 的类型,TypeScript 编译器需要继续判断入参 T 的类型,这就形成了一个循环引用,类似函数循环调用自己,如果没有正确的终止条件,就会一直处于无限循环的状态,所以就会报错。
2.TS2554
另一个常⻅的错误就是TS2554,它是由于形参和实参个数不匹配造成的,如下:
function test(a: number | undefined): string {
if (a=== undefined) {
return '';
}
return a.toString();
}
test(); // TS2554: Expected 1 arguments, but got 0.
test(undefined);
之所以会报错是因为在 ts 中,undefined 是一个特殊的类型,由于类型为 undefined,并不代表可 缺省,因此示例中的第 8 行提示了 TS2554 错误。
3.TS1169
TS1169 类型错误是在接口类型定义中由于使用了非字面量或者非唯一 symbol 类型作为属性名造成 的,如下:
interface Obj {
[key in 'id' | 'name']: any; // TS1169: A computed property name in an interface must refer to an expression whose type is a literal type or a 'unique symbol' type.
};
因为interface 类型的属性必须是字面量类型(string、number) 或者是 unique symbol 类型,所以 在第 2 行提示了 TS1169 错误。
4.TS2345
TS2345 类型错误的原因在于传参时由于类型不兼容造成的,如下:
enum A {
x = 'x',
y = 'y',
z = 'z',
}
enum B {
x = 'x',
y = 'y',
z = 'z',
}
function fn(val: A) {}
fn(B.x); // TS2345: Argument of type 'B.x' is not assignable to parameter of type 'A'. ;
如上所示,函数 fn 参数的 val 类型是枚举 A,在 12 行我们传入了与枚举 A 类似的枚举 B 的值,此时 ts 提示了类型不匹配的错误。这是因为枚举是在运行时真正存在的对象,因此 ts 并不会判断两个枚举是否可以互相兼容,所以报错。解决这个错误的方式也很简单,我们只需要让这两个枚举类型互相兼容就行,比如使用类型断言绕过 ts 的类型检查(fn((B.x as unknown) as A);)即可。
5.TS2589
TS2589 类型错误是由泛型实例化递归嵌套过深造成的,如下:
type RepeatX<N extends number, T extends any[] = []> = T['length'] extends N?T: RepeatX<N, [...T, 'X']>;
type T1 = RepeatX<5>; // => ["X", "X", "X", "X", "X"]
// TS2589: Type instantiation is excessively deep and possibly infinite.
因为第 1 行的泛型 RepeatX 接收了一个数字类型入参 N,并返回了一个⻓度为 N、元素都是 'X' 的数组类型,所以第 4 行的类型 T1 包含了 5 个 "X" 的数组类型;但是第 6 行的类型 T2 的类型却是 any,并且提 示了 TS2589 类型错误。这是因为 ts 在处理递归类型的时候,最多实例化 50 层,如果超出了递归层数的 限制,ts 便不会继续实例化,并且类型会变为 top 类型 any。 对于上面的错误,我们使用 @ts-ignore 注释忽略即可。
6.TS2322
TS2322 错误是由于字符串字面量类型定义时导致的错误,如下:
interface cssProperties {
display: 'block' | 'flex' | 'grid';
}
const style = {
display: 'flex',
};
// TS2322: Type '{ display: string; }' is not assignable to type 'CSSProperties'.
// Types of property 'display' are incompatible.
// Type 'string' is not assignable to type '"block" | "flex" | "grid"'.
const cssStyle: CSSProperties = style;
在上面的例子中,CSSProperties 的 display 属性的类型是字符串字面量类型 'block' | 'flex' | 'grid',虽然变量 style 的 display 属性看起来与 CSSProperties 类型完全兼容,但是 TypeScript 提示了 TS2322 类型不兼容的错 误。这是因为变量 style 的类型被自动推断成了 { display: string },string 类型自然无法兼容字符串字面量类型 'block' | 'flex' | 'grid',所以变量 style 不能赋值给 cssStyle。
以上六种便是项目开发中比较常见的几种错误类型,如果你想查看所有的错误信息和错误码,可以浏览TypeScript 的源代码仓库,当然,随着 ts 版本的更新,官网也会逐渐增加更多新的类型错误。
Recommend
-
60
前段时间有写过一个 TypeScript在node项目中的实践 。 在里边有解释了为什么要使用 TS ,以及在 Node 中的一...
-
35
原文:Common CSS Issues For Front-End Projects 作者:Ahmad Shadeed 发表时间:december 27, 2018 译者:西楼听雨 发表时间: 2019/01/01 (转载请注明出处) When imp
-
54
原文地址: Common CSS Issues For Front-End Projects 原文作者:Ahmad Shadeed 快速摘要:近年来...
-
37
上周发布了一款名为 Smartour 的工具,是完全采用 TypeScript (以下简...
-
12
在typeScript+vue项目中使用ref发布于 3 分钟前因为vue项目是无法直接操作dom的,但是有时候开发需求迫使我们去操作dom。两个办法,一个是很low的再引入jq,...
-
11
如何在项目中用好 TypeScript 🤔 2022年01月30日 05:36 · 阅读 3282
-
6
一些开源项目包含了各种编程的最佳实践供...
-
8
聊聊项目中定时任务的处理方式 一个项目中一般...
-
6
在Vue3+TypeScript 前端项目中使用事件总线Mitt ...
-
6
在基于vue-next-admin 的 Vue3+TypeScript 前端项目中,可以整合自己的 .NET 后端,前端操作一些功能的时候,为了使用方便全局挂载的对象接口,以便能够快速处理一些特殊的操作...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK