TSConfig文件详解09
编译器配置项-compilerOptions
类型检查相关配置项(六)
严格的函数类型-strictFunctionTypes
当启用strictFunctionTypes
时,TypeScript检查函数参数的类型更严格。
这是一个未启用strictFunctionTypes
选项的基本示例:
function fn(x: string) {
console.log("Hello, " + x.toLowerCase());
}
type StringOrNumberFunc = (ns: string | number) => void;
// Unsafe assignment
let func: StringOrNumberFunc = fn;
// Unsafe call - will crash
func(10);
启用strictFunctionTypes
后,可以正确检测到错误:
function fn(x: string) {
console.log("Hello, " + x.toLowerCase());
}
type StringOrNumberFunc = (ns: string | number) => void;
// Unsafe assignment is prevented
let func: StringOrNumberFunc = fn;
Type '(x: string) => void' is not assignable to type 'StringOrNumberFunc'.
Types of parameters 'x' and 'ns' are incompatible.
Type 'string | number' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.
在开发这个功能的过程中,我们发现了大量本质上不安全的类层次结构,包括 DOM 中的一些类。因此,这个选项仅对通过function
方法写的函数起作用,通过method
写的方法不起作用:
type Methodish = {
func(x: string | number): void;
};
function fn(x: string) {
console.log("Hello, " + x.toLowerCase());
}
// Ultimately an unsafe assignment, but not detected
const m: Methodish = {
func: fn,
};
m.func(10);
严格的null检查-strictNullChecks
当strictNullChecks
选项设置为false
时,TypeScript将忽略null
和undefined
,这会导致程序在运行时出现意外的错误。
当strictNullChecks
选项设置为true
时,null
和undefined
将具有不同的类型,如果在一个需要具体值的地方使用它们,将会出现类型错误的报告。
例如下边的TypeScript代码,虽然user.find
无法保证一定会找到一个user,但是你仍然可以这样写loggedInUser.age
:
declare const loggedInUsername: string;
const users = [
{ name: "Oby", age: 12 },
{ name: "Heera", age: 32 },
];
const loggedInUser = users.find((u) => u.name === loggedInUsername);
console.log(loggedInUser.age);
将strictNullChecks
设置为true
,将会报告一个错误:你无法保证在使用loggedInUser
之前它一定存在。
declare const loggedInUsername: string;
const users = [
{ name: "Oby", age: 12 },
{ name: "Heera", age: 32 },
];
const loggedInUser = users.find((u) => u.name === loggedInUsername);
console.log(loggedInUser.age);
'loggedInUser' is possibly 'undefined'.
第二个示例之所以失败,是因为Array
的find
方法简化后与下边的代码相似:
// When strictNullChecks: true
type Array = {
find(predicate: (value: any, index: number) => boolean): S | undefined;
};
// When strictNullChecks: false the undefined is removed from the type system,
// allowing you to write code which assumes it always found a result
type Array = {
find(predicate: (value: any, index: number) => boolean): S;
};
严格的属性初始化-strictPropertyInitialization
当启用strictPropertyInitialization
时,TypeScript将报告错误,如果一个class
定义了属性,但是在constructor
中未被设置值。
class UserAccount {
name: string;
accountType = "user";
email: string;
Property 'email' has no initializer and is not definitely assigned in the constructor.
address: string | undefined;
constructor(name: string) {
this.name = name;
// Note that this.email is not set
}
}
在上边的示例中:
-
this.name
的值已经明确设置 -
this.accountType
的值已经默认设置 -
this.email
的值未被设置,并且报告了错误 -
this.address
声明时已包含undefined
,这意味着它不需要设置值
在Catch变量中使用unknown变量-useUnknownInCatchVariables
在 TypeScript 4.0 中,添加了允许将 catch 子句中的变量类型从any
更改unknown
的支持,例如以下代码:
try {
// ...
} catch (err: unknown) {
// We have to verify err is an
// error before using it as one.
if (err instanceof Error) {
console.log(err.message);
}
}
此模式可确保错误处理代码变得更加全面,因为你无法在抛出错误对象之前保证抛出的对象是Error子类。启用useUnknownInCatchVariables
后,你不需要额外的语法(: unknown
)或者linter
规则来尝试强制执行此行为。