--strict标志包括以下标志:
--strictNullChecks--alwaysStrict--noImplicitAny--noImplicitThis--strictBindCallApply--strictFunctionTypes--strictPropertyInitialization我们给出示例并尝试在一个地方理解所有这些含义。// I. --strictNullChecks
TS中存在NPE的著名问题(空指针异常,十亿美元错误)。在TS中,默认情况下,所有类型都是Nullable,这意味着我们可以传递“ undefined” | 在任何其他类型(甚至是基本类型)都应为“ Null”的情况下:const bar1: { foo: number } = undefined;
const bar2: { foo: number } = null;
const bar3: number = null;
const bar4: string = null;
更有趣的例子是方法调用,它可能不是declare var smth: { optionalMethod?(): string; };
smth.optionalMethod();
这也暗示我们不能返回“ undefined”。显然不希望出现“空”function getIt(): { data: number } {
return undefined;
}
getIt().data;
我们必须明确指出“未定义”可以返回,只有在出现错误之后function getIt(): { data: number } | undefined {
return undefined;
}
getIt().data;
另外,更安全的操作是可能没有结果的操作是有一个错误,打开标志会出错,并且您必须明确检查“查找”是否发现了以下内容:
[{ name: 'John', age: 4 }]
.find(el => el.age === 42)
.name;
// II。-始终严格
向每个文件
添加“使用严格”注释,使JS行为更加明确// III。--noImplicitAny
禁止在TS中隐式使用“ any”,即 没有类型注释的代码
function id(arg) {
return arg;
}
对于建议安装类型定义的第三方库的无类型导入提供了很大的帮助
import * as session from '3rd-party-lib';
// IV。--strictBindCallApply
它包括对“绑定” /“呼叫” /“应用”的“更严格”类型检查,不带标志-这都是有效的TS。 function getFullName(name: string, surname: string): string {
return name + surname;
}
getFullName.call(null, 'John', 42);
getFullName.apply(null, ['John', 42]);
getFullName.bind(null)('John');
getFullName.bind(null, 'John')();
getFullName.bind(null, 'John')(42);
// V. --strictPropertyInitialization + --strictNullChecks
帮助跟踪所有属性是否已在构造函数中初始化;还必须启用--strictNullChecks以禁用Nullable类型。 class User {
name: string;
}
但是,如果赋值不在构造函数本身中,请说服TS一切正常。 class User2 {
name: string;
constructor(name: string) {
this.initializeName();
}
initializeName() {
this.name = 'John'
}
}
如果您不能使TS确信该属性将被完全初始化,则可以说“我发誓,妈妈一定会初始化!” 或更简短地说是“!”class User3 {
name!: string;
}
// VI。--strictFunctionTypes
消除了参数的双变量检查。变编程,总之-这是通过能力超类型 / 亚型出现,其中,类型的预期。例如,有一个层次结构Shape-> Circle-> Rectangle,如果需要Circle ,是否可以传输或返回Shape / Rectangle?
编程选项HABR,SOinterface Shape { name: string };
interface Circle extends Shape { width: number };
interface Rectangle extends Circle { height: number };
declare var logSC: (figure: Shape) => Circle;
declare var logRC: (figure: Rectangle) => Circle;
declare var logCC: (figure: Circle) => Circle;
declare var logCS: (figure: Circle) => Shape;
declare var logCR: (figure: Circle) => Rectangle;
declare var wlogBB: (fn: (figure: Circle) => Circle) => void;
wlogBB(logCC);
wlogBB(logSC);
wlogBB(logCR);
wlogBB(logCS);
wlogBB(logRC);
可以理解,该函数不应更改所传递的参数(充当类型生产者),TS中没有错误,实际上-const squares: Square[] = [{ name: 'Square', width: 5 }];
function addSmth(arg: Shape[]) {
arg.push({ name: 'Square' });
}
addSmth(squares);
// VII。--noImplicitThis
如果函数是在对象/类之外定义的,则TS将要求您使用名为“ this”的第一个伪参数来明确指出“ this”将指代什么。
function getName(this: { name: string }, surname: string): string {
return this.name;
}
getName.call({}, 'Smith');
getName.apply({}, ['Smith']);
getName.bind({})('Smith');
通话有效const somePerson = { name: 'John', getName };
const fullName: string = somePerson.getName('Smith')
getName.call({name: 'John'}, 'Smith');
getName.apply({name: 'John'}, ['Smith']);
getName.bind({name: 'John'})('Smith');
构造函数可能导致问题function Person(this: { name: string }, name: string) {
this.name = name;
}
const person = new Person('John');
一个有趣的好处是为类添加了上下文绑定方法的比较。class A {
x = 42;
constructor() {
this.getBound = this.getBound.bind(this);
}
getSimple(): number {
return this.x;
}
getSimpleAnnotated(this: A): number {
return this.x;
}
getArrow = (): number => this.x;
getBound(this: A): number {
return this.x;
}
}
const a = new A();
const getSimple = a.getSimple;
getSimple();
const getSimpleAnnotated = a.getSimpleAnnotated;
getSimpleAnnotated();
const getArrow = a.getArrow;
getArrow();
const getBound = a.getBound;
getBound();