TypeScript-思考類型使用具體情節

寫在最前面

  • 最近學習 ts,公司中大佬作了一次關於 ts 的分享,收穫頗豐,本身總結了一下筆記,下面給你們分享一下。
  • 第一篇主要是分享幾個關於 ts 類型的幾個細節的問題。

ts 類型

  • 基本類型
    • boolean、number、string、symbol、object、null、undefined
    • enum
    • array、tuple
    • any、void、never、unknown

思考問題?

  • 一、Object 和 object 的區別?
  • 二、String 和 string 的區別?
  • 三、null 和 undefined 的區別?
  • 三、any、void、never、unknown 的區別?

1.1 String 和 string 的區別?

  • 思考下面的代碼
'123' === new String('123') // ??
// false
typeof new String('123') // ??
// object
 
 //b 包裝類型
let a = '123', b = new String('123');
a.name = b.name = 'string';
console.log(a.name, b.name); // ??
複製代碼

上面的 a.name 會打印 undefined,b.name 能夠正常的打印出 'string'javascript

區分原始類型和包裝類型(wrapper object)

  • 而TS中的string、boolean、number等聲明類型,則是指原始的基本數據類型。
let str: string = new String(123); // error: Type 'String' is not assignable to type 'string'.
let str: string = '123'; // ok
let str: String = '123'; // ok
 
let a = new String(1234);
let: str: typeof '1234'; // str: string
let str: typeof a; //str: String
複製代碼

2.1 Object 和 object 的區別?

  • 在js中,Boolean、String、Number爲基本包裝類型的構造函數(類)。在TS中,他們在類型聲明上下文中,則指代接口定義:
interface String {
    /** Returns a string representation of a string. */
    toString(): string;
 
    /** * Returns the character at the specified index. * @param pos The zero-based index of the desired character. */
    charAt(pos: number): string;
 
    /** * Returns the Unicode value of the character at the specified location. * @param index The zero-based index of the desired character. If there is no character at the specified index, NaN is returned. */
    charCodeAt(index: number): number;
 
 
    ...
}

複製代碼

即,在TS中,new String(...) 這裏的String是指對於interface String的類實現(class implements)。java

  • 而在類型聲明上下文中,String則指的就是這個interface String。安全

  • 2.1.1 Object 其實也是一個接口聲明,能夠去看看 ts 源代碼的 Object 是怎麼聲明的。任意類型都是 Objectbash

let num: Object = 1; // ok
let str: Object = 'a'; // ok
let obj: Object = { foo: 123 }; // ok
let nul: Object = null; // error
let undef: Object = undefined; // error
 
 
obj.foo // error: Property 'foo' does not exist on type '{}'
obj.toString() // ok
複製代碼

事實上,聲明爲Object能夠賦予除了null、undefined之外的任意值!此時訪問這些聲明的變量,均可以訪問Object接口所定義的幾個基本方法。app

  • 2.1.2 {}:而空的花括號{}類型,則和Object很相似,一樣能夠接受任意類型的值。它是指空對象類型。聲明爲{}類型,則沒有任何成員變量能夠訪問(連Object.prototype.toString等方法都不能夠)
let num: {} = 1; // ok
let str: {} = 'a'; // ok
let obj: {} = { foo: 1234 }; // ok
let nul: {} = null; // error
let undef: {} = undefined; // error
 
 
obj.foo // error: Property 'foo' does not exist on type '{}'
obj.toString() // error: Property 'toString' does not exist on type '{}'

複製代碼
  • 2.1.3 object : object類型,則單純指代非string、number、boolean、symbol、null、undefined的其餘類型!與{}相似,一樣沒有任何成員屬性或方法能夠訪問!
// 這麼賦值
let num: object = 1; // error
let str: object = 'a'; // error
let obj: object = { foo: 1234 }; // ok
let nul: object = null; // error
let undef: object = undefined; // error
 
 
obj.foo // error: Property 'foo' does not exist on type 'object'
obj.toString() // error: Property 'toString' does not exist on type 'object'

複製代碼
  • 類型的檢測的寬泛度:類型限制範圍上:any > {} ~ Object > object

總結: 表示基本對象類型時,應當老是使用object類型,或者使用接口定義結構化對象。函數

3.1 null 和 undefined 的區別?

  • ts中也有null和undefined類型,聲明爲這兩種類型的值,也只能賦予同名值:
let a: null = null;
let b: undefined = undefined;
複製代碼
  • 在默認狀況下,null和undefined這兩個值(不是指類型!!)被看成其餘類型的子類型,便可以賦予任意其餘類型聲明的變量。可是在開啓了 --strictNullChecks 編譯選項後,他們則只能被賦予void類型,或者各自的同名類型。
let a: void = null;
let b: void = undefined;
複製代碼

4.1 any、void、never、unknown 的區別

  • 4.1.1 any ts 檢測弱,兼容性問題解決方案。
  • 成員訪問無限制
let user: any = {};
 
user.name // ok
複製代碼

如以上例子中,user被聲明爲any類型,即便其沒有name這個屬性,tsc也不會對其進行檢查。因此any能夠用來指代哪些由外部傳入、服務端返回等黑盒子結構的數據!!學習

  • 事實上,任意未明確聲明類型並切沒法推導出類型的值都默認爲any類型。
let a; // a: any
a = 1;
let a = 1; //a: number
複製代碼
  • 4.1.2 void

void應當僅僅用於函數聲明,即沒有明確返回值的函數,應該被聲明爲void類型。將void用戶變量聲明,則只能爲其賦予null或undefined。ui

  • 4.1.3 never

never用於函數返回值時,表示函數有拋出異常,沒有正常執行到底。用於變量聲明,沒法爲其賦予任何值!spa

never是全部類型的子類型而且能夠賦值給全部類型。 沒有類型是never的子類型或能賦值給never(never類型自己除外)。prototype

在函數表達式或箭頭函數沒有返回類型註解時,若是函數沒有return語句,或者只有never類型表達式的return語句,而且若是函數是不可執行到終點的(例如經過控制流分析決定的),則推斷函數的返回類型是never。

在有明確never返回類型註解的函數中,全部return語句(若是有的話)必須有never類型的表達式而且函數的終點必須是不可執行的。

  • never還能夠用於映射類型中表達式,用於刪除/過濾當前類型
let a: string | never; // a: string
type Exclude<T, K> = T extends K ? never: T;
複製代碼
  • 4.1.4 unknown

unknown相對於any,任意類型均可以賦值給unknow,可是不可對其進行任何訪問操做(僅僅爲類型安全,any操做訪問也安全)

let a: any = 123;
a.toFixed(); //ok
let a: unknown = 123;
a.toFixed(); // error
複製代碼

未完待續...

相關文章
相關標籤/搜索