成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

TypeScript 嚴格模式有多嚴格?

開發 前端
getAnimalName? 是比 getDogName 更廣泛的函數。因此,在這種情況下,無法將超類型分配給子類型。但是,可以將子類型分配給超類型。大多數時候,函數參數應該是逆變的,而不是雙向協變的。如果開啟嚴格模式,Typescript 將不會將函數參數視為雙向協變。

大家好,我是 CUGGZ。

TypeScript 是微軟于 2012 年推出的一門語言,它是 JavaScript 的超集,具有更強的可選類型系統。TypeScript 和 JavaScript 一樣是有嚴格模式的,今天就來看看 TypeScript 中的嚴格模式如何開啟,以及它到底有多嚴格!

TypeScript 的配置項都寫在項目根目錄名為 tsconfig.json 的配置文件中,可以通過以下方式來開啟嚴格模式:

{
...
"compilerOptions": {
"strict": true,
...
},
...
}

TypeScript 編譯器有超過 90 個不同的配置項。其中 7 個是關于嚴格模式的:

  • noImplicitAny
  • noImplicitThis
  • alwaysStrict
  • strictBindCallApply
  • strictNullChecks
  • strictPropertyInitialization
  • strictFunctionTypes

當在 tsconfig.json 中開啟嚴格模式之后,就相當于開啟了這些配置:

{
...
"compilerOptions": {
"noImplicitAny": true,
"noImplicitThis": true,
"alwaysStrict": true,
"strictBindCallApply": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
...
}
...
}

下面就來分別看一下這些選項都有什么含義。

noImplicitAny

此規則不允許變量或函數參數具有隱式 any 類型。來看下面的例子:

const add10 = number number + 10;

當啟用了嚴格模式時,函數參數 number 就報錯了:

參數“number”隱式具有“any”類型。ts(7006)

要想修復這個報錯,只需給參數或變量顯式指定類型:

const add10 = (number: number) => number + 10;

因此 noImplicitAny 規則可以確保代碼更具可讀性。否則,add10 函數的調用者需要推斷參數是一個數字,那使用 TypeScript 還有什么意義呢?

noImplicitThis

此規則不允許 this 隱式定義上下文。來看下面的例子:

class Person {
weight: number;
height: number;
constructor(weight: number, height: number) {
this.weight = weight;
this.height = height;
}
getBodyMassIndex() {
return function () {
return this.weight / (this.height * this.height);
};
}
}

當啟用了嚴格模式時,getBodyMassIndex 中的 this 就報錯了:

"this" 隱式具有類型 "any",因為它沒有類型注釋。ts(2683)

解決這個問題的方法就是使用箭頭函數,因為箭頭函數使用其父級的執行上下文:

class Person {
weight: number;
height: number;
constructor(weight: number, height: number) {
this.weight = weight;
this.height = height;
}
getBodyMassIndex() {
return () {
return this.weight / (this.height * this.height);
};
}
}

alwaysStrict

此規則指定始終以嚴格模式檢查每個模塊,并且在編譯之后的 JavaScript 文件中加入"use strict",用來告訴瀏覽器該 JavaScript 為嚴格模式。

ECMAScript 嚴格模式是在 ES5 中引入的,它只是向編譯器提示代碼應該以嚴格模式執行,使用嚴格模式可以使代碼更以更安全、高效的方式運行。

strictBindCallApply

此規則可以確保使用具有正確參數的 call()、bind() 和 apply() 函數。來看下面的例子:

const logNumber = (x: number) => {
console.log(`number:${x}`)
}

logNumber.call(undefined, "10"); //

當啟用了嚴格模式時,getBodyMassIndex 中的 this 就報錯了:

類型“string”的參數不能賦給類型“number”的參數。ts(2345)

當遇到這種報錯時,只需檢查函數調用的參數,并使用正常的方式調用:

logNumber.call(undefined, 10); // number:10

strictNullChecks

此規則使得 null和 undefined 值不能賦值給非這兩種類型的值,別的類型的值也不能賦給它們。除了 any 類型,還有個例外就是 undefined 可以賦值給 void 類型。這個選項可以幫助 Uncaught TypeError 錯誤。來看下面的例子:

interface Book {
name: string;
author: string;
}

const books: Book[] = [ {name: 'Test1', author: 'Max'} ];

const getBookByAuthor = (author: string) => books.find((book) => book.author = author);

const book = getBookByAuthor("John");

console.log(book.name);

當啟用了嚴格模式時,打印 book.name 時就報錯了:

對象可能為“未定義”。ts(2532)

如果未開啟嚴格模式,即使 book.name 可能未定義,此代碼也會編譯。想要修復這個問題,就需要為要編譯的代碼添加 null 檢查:

interface Book {
name: string;
author: string;
}

const books: Book[] = [ {name: 'Test1', author: 'Max'} ];

const getBookByAuthor = (author: string) => books.find((book) => book.author = author);

const book = getBookByAuthor("John");

if (book) {
console.log(book.name);
} else {
console.log('Book not found');
}

函數中也是一樣的,來看下面的例子:

interface Book {
name: string;
author: string;
}

const books: Book[] = [ {name: 'Test1', author: 'Max'} ];

const getBookByAuthor = (author: string) => books.find((book) => book.author = author);

const book = getBookByAuthor("John");

const logBookName = (book: Book) => {
console.log(book.name);
}

logBookName(book);

如果啟用了嚴格模式時,調用 logBookName(book); 時就會報錯:

類型“Book | undefined”的參數不能賦給類型“Book”的參數。
不能將類型“undefined”分配給類型“Book”。ts(2345)

這里提供兩種解決方案:

  • A:將logBookName 函數參數類型設置為 Book | undefined
  • B:null 檢查條件調用

// A
const logBookName = (book: Book | undefined) => {
if (book) {
console.log(book.name);
}
else {
console.log('not book');
}
}

// B
if (book) {
logBookName(book);
}

使用該規則時,可以強制開發人員編寫具有更好類型描述的代碼。

strictPropertyInitialization

此規則將強制在構造函數中初始化所有屬性值。來看下面的例子:

class User {
name: string;
age: number;
occupation: string | undefined;
constructor(name: string) {
this.name = name;
}
}

在上面的代碼塊中有一個 User 類,constructor() 方法是初始化其實例屬性的地方。當實例化一個類對象時,JavaScript 會自動調用 constructor() 方法。Typescript 要求要么初始化定義的屬性,要么指定一個 undefined 類型。因此,當編譯上面的代碼時,將會提示以下錯誤:

屬性“age”沒有初始化表達式,且未在構造函數中明確賦值。ts(2564)

對于上面的代碼,可以這樣改:

// A:指定 undefined 類型
class User {
name: string;
age: number | undefined;
occupation: string | undefined;
constructor(name: string) {
this.name = name;
}
}

// B:初始化定義的屬性
class User {
name: string;
age: number;
occupation: string | undefined;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
}

strictFunctionTypes

此規則會更徹底地檢查函數參數。Typescript 參數默認是雙向協變的,這意味著它們既可以是協變的,也可以是逆變的。方差是一種深入了解子類型關系的方法。當參數是協方差時,我們可以將特定類型分配給更廣泛的類型(例如將子類型分配給超類型)。逆變是相反的:可以將更廣泛的類型分配給特定類型(例如將超類型分配給子類型)。

// 非嚴格模式
interface Animal {
name: string;
}
interface Dog extends Animal {
breeds: Array<string>;
}
let getDogName = (dog: Dog) => dog.name;
let getAnimalName = (animal: Animal) => animal.name;
getDogName = getAnimalName; // Ok
getAnimalName = getDogName; // Ok

上面的代碼運行時并沒有提示錯誤,默認情況下參數是雙向協變比較的。超類型 getAnimalName 和子類型 getDogName 的方法可以相互分配。當開啟嚴格模式之后,則 TypeScript 的參數進行逆變比較。

// 嚴格模式
interface Animal {
name: string;
}
interface Dog extends Animal {
breeds: Array<string>;
}
let getDogName = (dog: Dog) => dog.name;
let getAnimalName = (animal: Animal) => animal.name;
getDogName = getAnimalName; // Ok
getAnimalName = getDogName; // Error

當開啟嚴格模式時,最后一行將報以下錯誤:

不能將類型“(dog: Dog) => string”分配給類型“(animal: Animal) => string”。
參數“dog”和“animal” 的類型不兼容。
類型 "Animal" 中缺少屬性 "breeds",但類型 "Dog" 中需要該屬性。ts(2322)

這里,getAnimalName 是比 getDogName 更廣泛的函數。因此,在這種情況下,無法將超類型分配給子類型。但是,可以將子類型分配給超類型。大多數時候,函數參數應該是逆變的,而不是雙向協變的。如果開啟嚴格模式,Typescript 將不會將函數參數視為雙向協變。

責任編輯:武曉燕 來源: 前端充電寶
相關推薦

2012-03-17 21:45:02

JavaScript

2017-04-17 21:33:01

前端開發javascript嚴格模式

2025-03-24 07:10:00

嚴格模式JavaScript代碼

2011-06-23 10:49:13

Qt 自定義信號

2023-11-01 06:50:15

2017-11-30 12:33:13

數據中心機房環境

2021-11-16 11:24:12

加密貨幣區塊鏈金融

2010-10-26 09:09:35

Android

2011-08-09 10:13:17

敏捷軟件敏捷大會敏捷中國

2015-12-31 09:58:50

混合云云遷移云管理

2011-08-15 10:10:47

編程

2014-08-28 11:12:14

谷歌

2012-11-26 16:53:03

2014-04-01 11:00:51

谷歌Android開發者政策

2012-04-29 10:25:04

APP

2012-05-11 09:50:34

2020-02-18 08:25:44

物聯網安全法規IOT

2021-06-01 09:34:07

面部識別人工智能AI

2020-06-04 08:13:36

JavaScriptObject.is()運算符

2024-11-13 10:30:00

機器學習算法
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 黄网站在线播放 | 国产高清在线观看 | 日本成人在线观看网站 | 黄色香蕉视频在线观看 | 亚洲欧美日韩中文字幕一区二区三区 | 97国产精品视频人人做人人爱 | 日本精品一区二区三区在线观看视频 | 久久久91精品国产一区二区三区 | 99久久亚洲 | 精国产品一区二区三区 | a在线v| 亚洲乱码国产乱码精品精98午夜 | 91欧美| 国产精品色 | 日韩在线中文字幕 | 亚洲 欧美 激情 另类 校园 | 一区精品在线观看 | 国产一区二区三区在线看 | 欧美电影免费网站 | 久久久久久中文字幕 | h在线播放 | 神马久久久久久久久久 | 久久91 | 久久视频精品 | 国产成人精品一区二区三区在线观看 | 欧美片网站免费 | 欧美午夜精品久久久久久浪潮 | 中文一区 | 91久久久久 | 国产精品无码永久免费888 | 中文一区二区 | 精品久久香蕉国产线看观看亚洲 | 欧美日韩国产一区二区 | 日日操天天射 | 日本不卡一区二区三区在线观看 | 播放一级黄色片 | 黄色片网站在线观看 | 欧美v日韩 | 福利电影在线 | 亚洲精彩视频在线观看 | 一区二区亚洲 |