当前位置:网站首页>How strict Typescript strict mode?
How strict Typescript strict mode?
2022-07-30 21:12:00 【Ink fragrance ^_^】
前言
"use strict"指令在JavaScript 1.8.5 (ECMAScript5)中新增.
至今,前端 er They basically turn on strict mode typing code by default..
那么,你知道TypescriptIn fact also have their own strict mode?
1.Typescript严格模式规则

当Typescript严格模式设置为on时,它将使用strictStrict typing rules under the family code validation for all files in the project.规则是:
| 规则名称 | 解释 |
|---|---|
noImplicitAny | 不允许变量或函数参数具有隐式any类型. |
noImplicitThis | 不允许this上下文隐式定义. |
strictNullChecks | 不允许出现null或undefined的可能性. |
strictPropertyInitialization | 验证构造函数内部初始化前后已定义的属性. |
strictBindCallApply | 对bind, call, apply更严格的类型检测. |
strictFunctionTypes | 对函数参数进行严格逆变比较. |
2.noImplicitAny
The rules do not allow the variable or function parameter is implicitany类型.请看以下示例:
// Javascript/Typescript 非严格模式
function extractIds (list) {
return list.map(member => member.id)
}
The above example is not correctlist进行类型限制,map循环了item的形参member.而在Typescript严格模式下,会出现以下报错:
// Typescript 严格模式
function extractIds (list) {
// ^^^^
// Parameter 'list' implicitly
// has an 'any' type. ts(7006)
return list.map(member => member.id)
// ^^^^^^
// Parameter 'member' implicitly
// has an 'any' type. ts(7006)
}
Correct spelling should be:
// Typescript 严格模式
interface Member {
id: number
name: string
}
function extractIds (list: Member[]) {
return list.map(member => member.id)
}
1.1 How to handle the browser's own events?
浏览器自带事件,比如e.preventDefault(),is the key code to prevent the default behavior of the browser.
这在TypescriptError in strict mode:
// Typescript 严格模式
function onChangeCheckbox (e) {
// ^
// Parameter 'e' implicitly
// has an 'any' type. ts(7006)
e.preventDefault()
const value = e.target.checked
validateCheckbox(value)
}
![]()
If you need to use it normallyWeb API,You need to define the extension globally.比如:
// Typescript 严格模式
interface ChangeCheckboxEvent extends MouseEvent {
target: HTMLInputElement
}
function onChangeCheckbox (e: ChangeCheckboxEvent) {
e.preventDefault()
const value = e.target.checked
validateCheckbox(value)
}
1.2 Third-party libraries also need to define types
请注意,If importedTypescript库,This also throws an error,because the type of the imported library isany.
// Typescript 严格模式
import { Vector } from 'sylvester'
// ^^^^^^^^^^^
// Could not find a declaration file
// for module 'sylvester'.
// 'sylvester' implicitly has an 'any' type.
// Try `npm install @types/sylvester`
// if it exists or add a new declaration (.d.ts)
// file containing `declare module 'sylvester';`
// ts(7016)
This may be a reconstruction projectTypescriptversion of a big trouble,Need to specifically define the third-party library interface type
3.noImplicitThis
This rule does not allowthis上下文隐式定义.请看以下示例:
// Javascript/Typescript 非严格模式
function uppercaseLabel () {
return this.label.toUpperCase()
}
const config = {
label: 'foo-config',
uppercaseLabel
}
config.uppercaseLabel()
// FOO-CONFIG
在非严格模式下,this指向config对象.this.labeljust searchconfig.label.
但是,thisReferences on functions can be ambiguous:
// Typescript严格模式
function uppercaseLabel () {
return this.label.toUpperCase()
// ^^^^
// 'this' implicitly has type 'any'
// because it does not have a type annotation. ts(2683)
}
如果单独执行this.label.toUpperCase(),则会因为this上下文configError no longer exists,因为label未定义.
One way to solve this problem is to avoidthisUse function without context:
// Typescript严格模式
const config = {
label: 'foo-config',
uppercaseLabel () {
return this.label.toUpperCase()
}
}
A better way is to write an interface,Define all types,而不是Typescript来推断:
// Typescript严格模式
interface MyConfig {
label: string
uppercaseLabel: (params: void) => string
}
const config: MyConfig = {
label: 'foo-config',
uppercaseLabel () {
return this.label.toUpperCase()
}
}
4.strictNullChecks
This rule does not allow出现null或undefined的可能性.请看以下示例:
// Typescript 非严格模式
function getArticleById (articles: Article[], id: string) {
const article = articles.find(article => article.id === id)
return article.meta
}
Typescript非严格模式下,这样写不会有任何问题.But strict mode will give you some shit.:
“你这样不行,万一finddid not match any value?”:
// Typescript严格模式
function getArticleById (articles: Article[], id: string) {
const article = articles.find(article => article.id === id)
return article.meta
// ^^^^^^^
// Object is possibly 'undefined'. ts(2532)
}
“I star you star!”
于是你会将改成以下模样:
// Typescript严格模式
function getArticleById (articles: Article[], id: string) {
const article = articles.find(article => article.id === id)
if (typeof article === 'undefined') {
throw new Error(`Could not find an article with id: ${id}.`)
}
return article.meta
}
“真香!”
![]()
5.strictPropertyInitialization
此规则将验证构造函数内部初始化前后已定义的属性.
必须要确保每个实例的属性都有初始值,可以在构造函数里或者属性定义时赋值.
(strictPropertyInitialization,This stinky name is so similarReactNumerous arbitrary properties in the source code)
请看以下示例:
// Typescript非严格模式
class User {
username: string;
}
const user = new User();
const username = user.username.toLowerCase();
如果启用严格模式,The type checker will report further errors:
class User {
username: string;
// ^^^^^^
// Property 'username' has no initializer
// and is not definitely assigned in the constructor
}
const user = new User();
/
const username = user.username.toLowerCase();
// ^^^^^^^^^^^^
// TypeError: Cannot read property 'toLowerCase' of undefined
There are four solutions.
方案#1:允许undefined
为usernameproperty definitions provide aundefined类型:
class User {
username: string | undefined;
}
const user = new User();
username属性可以为string | undefined类型,但这样写,Need to make sure the value isstring类型:
const username = typeof user.username === "string"
? user.username.toLowerCase()
: "n/a";
这也太不Typescript了.
方案#2:Explicit initialization of property values
这个方法有点笨,But quite effective:
class User {
username = "n/a";
}
const user = new User();
// OK
const username = user.username.toLowerCase();
方案#3:在构造函数中赋值
The most useful solution is tousernameThe constructor adds parameters,然后将其分配给username属性.
这样,无论何时new User(),Both must provide default values as parameters:
class User {
username: string;
constructor(username: string) {
this.username = username;
}
}
const user = new User("mariusschulz");
// OK
const username = user.username.toLowerCase();
还可以通过publicModifiers simplify further:
class User {
constructor(public username: string) {}
}
const user = new User("mariusschulz");
// OK
const username = user.username.toLowerCase();
方案#4:显式赋值断言
在某些场景下,Properties are initialized indirectly(Use helper methods or a dependency injection library).
这种情况下,You can use on properties显式赋值断言to help the type system identify types.
class User {
username!: string;
constructor(username: string) {
this.initialize(username);
}
private initialize(username: string) {
this.username = username;
}
}
const user = new User("mariusschulz");
// OK
const username = user.username.toLowerCase();
通过向该username属性添加一个明确的赋值断言,We tell the type checker:username,even if it can't detect the property itself,Can also expect this property is initialized.
6.strictBindCallApply
This rule willbind, call, applyDetect types more strictly.
啥意思?请看以下示例:
// JavaScript
function sum (num1: number, num2: number) {
return num1 + num2
}
sum.apply(null, [1, 2])
// 3
when you don't remember the parameter type,Parameter type and number are not checked in non-strict mode,运行代码时,Typescript和环境(可能是浏览器)neither throws an error:
// Typescript非严格模式
function sum (num1: number, num2: number) {
return num1 + num2
}
sum.apply(null, [1, 2, 3])
// 还是...3?
而Typescript严格模式下,这是不被允许的:
// Typescript严格模式
function sum (num1: number, num2: number) {
return num1 + num2
}
sum.apply(null, [1, 2, 3])
// ^^^^^^^^^
// Argument of type '[number, number, number]' is not
// assignable to parameter of type '[number, number]'.
// Types of property 'length' are incompatible.
// Type '3' is not assignable to type '2'. ts(2345)
那怎么办?“...”扩展运算符和reduceOld friends to rescue:
// Typescript严格模式
function sum (...args: number[]) {
return args.reduce<number>((total, num) => total + num, 0)
}
sum.apply(null, [1, 2, 3])
// 6
7. strictFunctionTypes
This rule will check and restrict function type parameters to be invariant(contravariantly)rather than double(bivariantly,covariant or resistant)的.
初看,内心 OS:“这什么玩意儿?”,Here is an introduction:
协变(covariance)and anti-mutation(contravariance)是什么?[1]
Covariance and Contravariance are complicated as written on the wiki,But to sum up, the principle is actually one.
Subtypes can be implicitly converted to supertypes
Give an easy-to-understand example,int和floatTwo types of relations can be written as follows.int≦float:也就是说int是float的子类型.
This stricter check applies to all function types except method or constructor declarations.methods are specifically excluded to ensure classes and interfaces with generics(如 Array )Overall still remains covariant.
请看下面这个Animal是Dog和CatAn example of a supertype of:
declare let f1: (x: Animal) => void;
declare let f2: (x: Dog) => void;
declare let f3: (x: Cat) => void;
f1 = f2; // 启用 --strictFunctionTypes 时错误
f2 = f1; // 正确
f2 = f3; // 错误
The first assignment statement is allowed in the default type checking mode,But in strict function type mode it will be flagged incorrectly.
while strict function typing mode marks it as an error,因为它不能 justified.
in any mode,The third assignment is all wrong,因为它 never reasonable.
Another way to describe this example would be,In default type checking modeT在类型(x: T) => void是 bivariate,But in the strict pattern function typesT是 抗变的:
interface Comparer<T> {
compare: (a: T, b: T) => number;
}
declare let animalComparer: Comparer<Animal>;
declare let dogComparer: Comparer<Dog>;
animalComparer = dogComparer; // 错误
dogComparer = animalComparer; // 正确

写到此处,Killed a rookie front end.
总结&参考
参考文章:
How strict is Typescript’s strict mode?[2]
How to understand covariant contravariance in programming languages?[3]
TypeScript strict function type[4]
在面试的过程中,常被问到为什么Typescript比JavaScript好用?
from these strict mode rules,You can get a glimpse of the mystery,Strictly open today,他日 Bug Flip the pot in seconds,噢耶.
边栏推荐
猜你喜欢

Cookie中的JSESSIONID说明

2021年软件测试面试题大全

LeetCode·23.合并K个升序链表·递归·迭代

C语言中指针没那么难~ (1)【文章结尾有资料】
![[The Beauty of Software Engineering - Column Notes] 31 | Is software testing responsible for product quality?](/img/6a/640763e3bd6c28f3e7fa762798b0ae.png)
[The Beauty of Software Engineering - Column Notes] 31 | Is software testing responsible for product quality?

新书上市 |《谁在掷骰子?》在“不确定性时代”中确定前行

【机器学习】梯度下降背后的数学之美

MYSQL JDBC图书管理系统

手把手教你搭建一台永久运行的个人服务器

Image Restoration by Estimating Frequency Distribution of Local Patches
随机推荐
HJ85 最长回文子串
Typescript 严格模式有多严格?
Cookie中的JSESSIONID说明
Outsourcing worked for three years, it was abolished...
MySQL group_concat()详解
字节对齐之C语言犄角旮旯的知识
R package调试
js堆和栈
tcp协议传输中的粘包问题
socket:内核初始化及创建流(文件)详细过程
QUALITY-GATED CONVOLUTIONAL LSTM FOR ENHANCING COMPRESSED VIDEO
MySQL 视图(详解)
LeetCode·每日一题·952.按公因数计算最大组件大小·并查集
如何制作deb包
Generate OOM records in a production environment. Conclusion: Don't be lazy to query useless fields unless you are completely sure.
Flex布局详解
为什么那么多自学软件测试的人,后来都放弃了...
bgp路由过滤
【网络安全专栏目录】--企鹅专栏导航
7、MySQL Workbench 导出导入数据库