TypeScript 繼承了 JavaScript 的類型,在這個(gè)基礎(chǔ)上钧忽,定義了一套自己的類型系統(tǒng)。
基本類型
概述
JavaScript 語(yǔ)言(注意逼肯,不是 TypeScript)將值分成8種類型耸黑。
- boolean
- string
- number
- bigint
- symbol
- object
- undefined
- null
TypeScript 繼承了 JavaScript 的類型設(shè)計(jì),以上8種類型可以看作 TypeScript 的基本類型篮幢。
注意大刊,上面所有類型的名稱都是小寫字母,首字母大寫的Number
三椿、String
缺菌、Boolean
等在 JavaScript 語(yǔ)言中都是內(nèi)置對(duì)象葫辐,而不是類型名稱。
另外伴郁,undefined 和 null 既可以作為值耿战,也可以作為類型,取決于在哪里使用它們焊傅。
這8種基本類型是 TypeScript 類型系統(tǒng)的基礎(chǔ)剂陡,復(fù)雜類型由它們組合而成。
以下是它們的簡(jiǎn)單介紹狐胎。
boolean 類型
boolean
類型只包含true
和false
兩個(gè)布爾值鸭栖。
const x:boolean = true;
const y:boolean = false;
上面示例中,變量x
和y
就屬于 boolean 類型握巢。
string 類型
string
類型包含所有字符串晕鹊。
const x:string = 'hello';
const y:string = `${x} world`;
上面示例中,普通字符串和模板字符串都屬于 string 類型暴浦。
number 類型
number
類型包含所有整數(shù)和浮點(diǎn)數(shù)溅话。
const x:number = 123;
const y:number = 3.14;
const z:number = 0xffff;
上面示例中,整數(shù)肉渴、浮點(diǎn)數(shù)和非十進(jìn)制數(shù)都屬于 number 類型公荧。
bigint 類型
bigint 類型包含所有的大整數(shù)。
const x:bigint = 123n;
const y:bigint = 0xffffn;
上面示例中同规,變量x
和y
就屬于 bigint 類型循狰。
bigint 與 number 類型不兼容。
const x:bigint = 123; // 報(bào)錯(cuò)
const y:bigint = 3.14; // 報(bào)錯(cuò)
上面示例中券勺,bigint
類型賦值為整數(shù)和小數(shù)绪钥,都會(huì)報(bào)錯(cuò)。
注意关炼,bigint 類型是 ES2020 標(biāo)準(zhǔn)引入的程腹。如果使用這個(gè)類型,TypeScript 編譯的目標(biāo) JavaScript 版本不能低于 ES2020(即編譯參數(shù)target
不低于es2020
)儒拂。
symbol 類型
symbol 類型包含所有的 Symbol 值寸潦。
const x:symbol = Symbol();
上面示例中,Symbol()
函數(shù)的返回值就是 symbol 類型社痛。
symbol 類型的詳細(xì)介紹见转,參見《Symbol》一章。
object 類型
根據(jù) JavaScript 的設(shè)計(jì)蒜哀,object 類型包含了所有對(duì)象斩箫、數(shù)組和函數(shù)。
const x:object = { foo: 123 };
const y:object = [1, 2, 3];
const z:object = (n:number) => n + 1;
上面示例中,對(duì)象乘客、數(shù)組狐血、函數(shù)都屬于 object 類型。
undefined 類型易核,null 類型
undefined 和 null 是兩種獨(dú)立類型匈织,它們各自都只有一個(gè)值。
undefined 類型只包含一個(gè)值undefined
耸成,表示未定義(即還未給出定義报亩,以后可能會(huì)有定義)。
let x:undefined = undefined;
上面示例中井氢,變量x
就屬于 undefined 類型弦追。兩個(gè)undefined
里面,第一個(gè)是類型花竞,第二個(gè)是值劲件。
null 類型也只包含一個(gè)值null
,表示為空(即此處沒有值)约急。
const x:null = null;
上面示例中零远,變量x
就屬于 null 類型。
注意厌蔽,如果沒有聲明類型的變量牵辣,被賦值為undefined
或null
,它們的類型會(huì)被推斷為any
奴饮。
let a = undefined; // any
const b = undefined; // any
let c = null; // any
const d = null; // any
如果希望避免這種情況纬向,則需要打開編譯選項(xiàng)strictNullChecks
。
// 打開編譯設(shè)置 strictNullChecks
let a = undefined; // undefined
const b = undefined; // undefined
let c = null; // null
const d = null; // null
上面示例中戴卜,打開編譯設(shè)置strictNullChecks
以后逾条,賦值為undefined
的變量會(huì)被推斷為undefined
類型,賦值為null
的變量會(huì)被推斷為null
類型投剥。
包裝對(duì)象類型
包裝對(duì)象的概念
JavaScript 的8種類型之中师脂,undefined
和null
其實(shí)是兩個(gè)特殊值,object
屬于復(fù)合類型江锨,剩下的五種屬于原始類型(primitive value)吃警,代表最基本的笑跛、不可再分的值削茁。
- boolean
- string
- number
- bigint
- symbol
上面這五種原始類型的值斟冕,都有對(duì)應(yīng)的包裝對(duì)象(wrapper object)溶其。所謂“包裝對(duì)象”,指的是這些值在需要時(shí)哨啃,會(huì)自動(dòng)產(chǎn)生的對(duì)象割粮。
'hello'.charAt(1) // 'e'
上面示例中争便,字符串hello
執(zhí)行了charAt()
方法浮毯。但是完疫,在 JavaScript 語(yǔ)言中,只有對(duì)象才有方法债蓝,原始類型的值本身沒有方法壳鹤。這行代碼之所以可以運(yùn)行,就是因?yàn)樵谡{(diào)用方法時(shí)饰迹,字符串會(huì)自動(dòng)轉(zhuǎn)為包裝對(duì)象芳誓,charAt()
方法其實(shí)是定義在包裝對(duì)象上。
這樣的設(shè)計(jì)大大方便了字符串處理啊鸭,省去了將原始類型的值手動(dòng)轉(zhuǎn)成對(duì)象實(shí)例的麻煩锹淌。
五種包裝對(duì)象之中,symbol 類型和 bigint 類型無(wú)法直接獲取它們的包裝對(duì)象(即Symbol()
和BigInt()
不能作為構(gòu)造函數(shù)使用)赠制,但是剩下三種可以赂摆。
Boolean()
String()
Number()
以上三個(gè)構(gòu)造函數(shù),執(zhí)行后可以直接獲取某個(gè)原始類型值的包裝對(duì)象钟些。
const s = new String('hello');
typeof s // 'object'
s.charAt(1) // 'e'
上面示例中烟号,s
就是字符串hello
的包裝對(duì)象,typeof
運(yùn)算符返回object
政恍,不是string
汪拥,但是本質(zhì)上它還是字符串,可以使用所有的字符串方法篙耗。
注意迫筑,String()
只有當(dāng)作構(gòu)造函數(shù)使用時(shí)(即帶有new
命令調(diào)用),才會(huì)返回包裝對(duì)象鹤树。如果當(dāng)作普通函數(shù)使用(不帶有new
命令)铣焊,返回就是一個(gè)普通字符串。其他兩個(gè)構(gòu)造函數(shù)Number()
和Boolean()
也是如此罕伯。
包裝對(duì)象類型與字面量類型
由于包裝對(duì)象的存在曲伊,導(dǎo)致每一個(gè)原始類型的值都有包裝對(duì)象和字面量?jī)煞N情況。
'hello' // 字面量
new String('hello') // 包裝對(duì)象
上面示例中追他,第一行是字面量坟募,第二行是包裝對(duì)象,它們都是字符串邑狸。
為了區(qū)分這兩種情況懈糯,TypeScript 對(duì)五種原始類型分別提供了大寫和小寫兩種類型。
- Boolean 和 boolean
- String 和 string
- Number 和 number
- BigInt 和 bigint
- Symbol 和 symbol
其中单雾,大寫類型同時(shí)包含包裝對(duì)象和字面量?jī)煞N情況赚哗,小寫類型只包含字面量她紫,不包含包裝對(duì)象。
const s1:String = 'hello'; // 正確
const s2:String = new String('hello'); // 正確
const s3:string = 'hello'; // 正確
const s4:string = new String('hello'); // 報(bào)錯(cuò)
上面示例中屿储,String
類型可以賦值為字符串的字面量贿讹,也可以賦值為包裝對(duì)象。但是够掠,string
類型只能賦值為字面量民褂,賦值為包裝對(duì)象就會(huì)報(bào)錯(cuò)。
建議只使用小寫類型疯潭,不使用大寫類型赊堪。因?yàn)榻^大部分使用原始類型的場(chǎng)合,都是使用字面量竖哩,不使用包裝對(duì)象哭廉。而且,TypeScript 把很多內(nèi)置方法的參數(shù)期丰,定義成小寫類型群叶,使用大寫類型會(huì)報(bào)錯(cuò)。
const n1:number = 1;
const n2:Number = 1;
Math.abs(n1) // 1
Math.abs(n2) // 報(bào)錯(cuò)
上面示例中钝荡,Math.abs()
方法的參數(shù)類型被定義成小寫的number
街立,傳入大寫的Number
類型就會(huì)報(bào)錯(cuò)。
上一小節(jié)說過埠通,Symbol()
和BigInt()
這兩個(gè)函數(shù)不能當(dāng)作構(gòu)造函數(shù)使用赎离,所以沒有辦法直接獲得 symbol 類型和 bigint 類型的包裝對(duì)象,因此Symbol
和BigInt
這兩個(gè)類型雖然存在端辱,但是完全沒有使用的理由梁剔。
Object 類型與 object 類型
TypeScript 的對(duì)象類型也有大寫Object
和小寫object
兩種。
Object 類型
大寫的Object
類型代表 JavaScript 語(yǔ)言里面的廣義對(duì)象舞蔽。所有可以轉(zhuǎn)成對(duì)象的值荣病,都是Object
類型,這囊括了幾乎所有的值渗柿。
let obj:Object;
obj = true;
obj = 'hi';
obj = 1;
obj = { foo: 123 };
obj = [1, 2];
obj = (a:number) => a + 1;
上面示例中个盆,原始類型值、對(duì)象朵栖、數(shù)組颊亮、函數(shù)都是合法的Object
類型。
事實(shí)上陨溅,除了undefined
和null
這兩個(gè)值不能轉(zhuǎn)為對(duì)象终惑,其他任何值都可以賦值給Object
類型。
let obj:Object;
obj = undefined; // 報(bào)錯(cuò)
obj = null; // 報(bào)錯(cuò)
上面示例中门扇,undefined
和null
賦值給Object
類型雹有,就會(huì)報(bào)錯(cuò)偿渡。
另外,空對(duì)象{}
是Object
類型的簡(jiǎn)寫形式件舵,所以使用Object
時(shí)常常用空對(duì)象代替卸察。
let obj:{};
obj = true;
obj = 'hi';
obj = 1;
obj = { foo: 123 };
obj = [1, 2];
obj = (a:number) => a + 1;
上面示例中,變量obj
的類型是空對(duì)象{}
铅祸,就代表Object
類型。
顯然合武,無(wú)所不包的Object
類型既不符合直覺临梗,也不方便使用。
object 類型
小寫的object
類型代表 JavaScript 里面的狹義對(duì)象稼跳,即可以用字面量表示的對(duì)象盟庞,只包含對(duì)象、數(shù)組和函數(shù)汤善,不包括原始類型的值什猖。
let obj:object;
obj = { foo: 123 };
obj = [1, 2];
obj = (a:number) => a + 1;
obj = true; // 報(bào)錯(cuò)
obj = 'hi'; // 報(bào)錯(cuò)
obj = 1; // 報(bào)錯(cuò)
上面示例中,object
類型不包含原始類型值红淡,只包含對(duì)象不狮、數(shù)組和函數(shù)。
大多數(shù)時(shí)候在旱,我們使用對(duì)象類型摇零,只希望包含真正的對(duì)象,不希望包含原始類型桶蝎。所以驻仅,建議總是使用小寫類型object
,不使用大寫類型Object
登渣。