- Smarter Type Alias Preservation
- Leading/Middle Rest Elements in Tuple Types
- Stricter Checks For The
in
Operator --noPropertyAccessFromIndexSignature
abstract
Construct Signatures- Understanding Your Project Structure With
--explainFiles
- Improved Uncalled Function Checks in Logical Expressions
- Destructured Variables Can Be Explicitly Marked as Unused
- Declare Missing Helper Function
Smarter Type Alias Preservation
type BasicPrimitive = number | string | boolean;
export function doStuff(value: BasicPrimitive) {
if (Math.random() < 0.5) {
return undefined;
}
return value;
}
这个方法中,如果我们获取到内部声明文件,doStuff 返回的类型是
export declare type BasicPrimitive = number | string | boolean;
export declare function doStuff(value: BasicPrimitive): string | number | boolean | undefined;
4.2 之后,我们得到的是
export declare type BasicPrimitive = number | string | boolean;
export declare function doStuff(value: BasicPrimitive): BasicPrimitive | undefined;
Leading/Middle Rest Elements in Tuple Types
基本类型 元组
首先复习一下元组的知识点:
// 一对数字类型的元组类型
let a: [number, number] = [1, 2];
// 存储字符串、数字、布尔值的元组类型
let b: [string, number, boolean] = ["hello", 42, true];
// 可以有一个或两个字符串的元组类型
let c: [string, string?] = ["hello"];
c = ["hello", "world"];
// 可以有一个或两个字符串并添加别名的元组类型
let d: [first: string, second?: string] = ["hello"];
d = ["hello", "world"];
// 通过使用rest element,首两位是字符串类型,其余都是布尔类型的元组类型
let e: [string, string, ...boolean[]];
e = ["hello", "world"];
e = ["hello", "world", false];
e = ["hello", "world", true, false, true];
4.2 之前,...rest
elements 只能放在元组的最后位置,而现在,rest element 可以放在元组的任何位置(只有一点点限制):
// rest element 放在前面,Leading Rest Elements
let foo: [...string[], number];
foo = [123];
foo = ["hello", 123];
foo = ["hello!", "hello!", "hello!", 123];
// rest element 放在中间,Middle Rest Elements
let bar: [boolean, ...string[], boolean];
bar = [true, false];
bar = [true, "some text", false];
bar = [true, "some", "separated", "text", false];
唯一的限制就是,rest element 后面不能跟着可选元素或者其他rest element。换句话说,一个元组类型只能有一个rest element,并且 rest element 后面不能跟着可选元素。
interface Clown { /*...*/ }
interface Joker { /*...*/ }
let StealersWheel: [...Clown[], "me", ...Joker[]];
// ~~~~~~~~~~ Error!
// A rest element cannot follow another rest element.
let StringsAndMaybeBoolean: [...string[], boolean?];
// ~~~~~~~~ Error!
// An optional element cannot follow a rest element.
这种不在尾部的rest element,可以帮我们拿到任前面何个数相同的参数,加上后面一点其余类型的参数:
declare function doStuff(...args: [...names: string[], shouldCapitalize: boolean]): void;
doStuff(/*shouldCapitalize:*/ false)
doStuff("fee", "fi", "fo", "fum", /*shouldCapitalize:*/ true);
Stricter Checks For The in
Operator
在 in
操作符的右侧使用非对象类型是一个运行时错误。TypeScript 4.2确保可以在设计时捕获它。
"foo" in 42
// ~~
// error! The right-hand side of an 'in' expression must not be a primitive.
--noPropertyAccessFromIndexSignature
tsconfig 配置
当我们访问对象属性,可以使用中括号语法,或者点操作符:
interface Person {
name: string;
}
const p: Person = { name: 'Max };
console.log(p.name) // Max
console.log(p['name']) // Max
有一种情况可能导致访问不明确的属性而不报错:
interface Person {
name: string;
[key: string]: string;
}
const p: Person = { name: 'Max };
console.log(p.namme) // undefined
console.log(p['namme']) // undefined
因为 “namme” 满足 [key: string]
。当开启--noPropertyAccessFromIndexSignature
配置,通过点操作符访问的不明确属性会被警告(但是中括号语法不会被警告)。
interface Person {
name: string;
[key: string]: string;
}
const p: Person = { name: 'Max' };
console.log(p.namme)
// ^^^^^^^^
// Error
console.log(p['namme']) // works fine
该配置项并不在 strict
family 中,因为它还不适用于大多数开发者。
abstract
Construct Signatures
Understanding Your Project Structure With --explainFiles
Improved Uncalled Function Checks in Logical Expressions
在 --strictNullChecks
开启情况下,在表达式 &&
和 ||
的情况下,使用未调用的函数,会报错:
function shouldDisplayElement(element: Element) {
// ...
return true;
}
function getVisibleItems(elements: Element[]) {
return elements.filter(e => shouldDisplayElement && e.children.length)
// ~~~~~~~~~~~~~~~~~~~~
// This condition will always return true since the function is always defined.
// Did you mean to call it instead.
}
Destructured Variables Can Be Explicitly Marked as Unused
在 noUnusedLocals
开启的情况下,未使用的变量名会报错:
let [_first, second] = getValues();
现在,在变量名前加下划线,意味着我们不准备使用它。
Declare Missing Helper Function
未命名的的函数名,可以根据调用快速 quick fix,添加方法和类型:
参考: