本文为系列文章《TypeScript 简明教程》中的一篇。javascript
从这篇文章,咱们开始讲解 TypeScript 的类型系统。以前咱们说到,TypeScript 是 JavaScript 的超集,是 JavaScript 的继承与发展,即所谓的『加强版』。这一点,从 TypeScript 中的基本类型能够看出。TS 的数据类型与 JS 几乎相同,此外还额外提供一些数据类型方便咱们使用。前端
首先,咱们来看 JavaScript 中 6 种原始数据类型在 TypeScript 中的使用,它们分别为:number
、string
、boolean
、null
、undefined
、symbol
。java
number
类型TypeScript 中,使用 number
表示变量为数值类型。与 JavaScript 一致,TypeScript 中全部数值都是浮点数,支持二进制、八进制、十进制和十六进制四种表示方法。es6
let decimalNumber: number = 42
let hexNumber: number = 0x2A
let binaryNumber: number = 0b101010
let octalNumber: number = 0o52
复制代码
二进制和八进制表示采用 ES6 新的写法,分别使用前缀 `0b`(或 `0B`)和 `0o`(或 `0O` 英文字母 O)表示。从 ES5 开始,再也不容许使用前缀 `0` 表示八进制。若是 `tsconfig` 中 target 高于 ES5 版本,TypeScript 将会出现提示:禁止使用前缀 `0` 表示八进制。 编程
除了浮点数之外,JavaScript 中还有一组特别的数值:Infinity
、-Infinity
、NaN
,它们也属于 number
类型。编程语言
const positiveLargestNumber: number = Infinity
const negativeLargestNumber: number = -Infinity
const notANumber: number = NaN
复制代码
Infinity
即正无穷,用以表示超出 JS 所能表示的最大值的数值,不一样环境下这个值有所不一样,可经过 Number.MAX_VALUE
查看,通常为 1.7976931348623157E+308
。与之相对应的是 -Infinity
,表示负无穷。函数
注意区分**负无穷**和**无穷小**两个概念。负无穷表示比任何数都小的一个负数值,无穷小表示以 0 为极限,无限趋于零的一个正数值。JS 中的无穷小值可经过 `Number.MIN_VALUE` 查看,通常为 `5E-324`。 post
NaN
表示一个本应返回数值的操做数未返回数值的状况。好比:学习
let newNumber: number = Number('a') // => NaN
复制代码
更多内容能够参考:ECMAScript 6 入门 - 数值的扩展ui
string
类型和其余编程语言同样,字符串是必不可少的一种类型,用于表示文本数据。能够经过 string
声明某个变量为字符串类型。
const theAnswer: number = 42
let sentence: string = `The Answer to the Ultimate Question of Life, The Universe, and Everything is ${ theAnswer }.`
复制代码
TypeScript 中你依旧可使用双引号("
)和单引号('
)来表示字符串。除此之外,你还可使用 ES6 提供的 模板字符串 语法。TypeScript 会自动将其编译为字符串拼接的形式。
// 编译结果
var theAnswer = 42;
var sentence = "The Answer to the Ultimate Question of Life, The Universe, and Everything is " + theAnswer + ".";
复制代码
boolean
类型布尔值能够说是最基本的数据类型了,它的可能取值只有两个:true
、false
。TypeScript 中使用 boolean
表示布尔值类型。
let num: number = -10
let isPositive: boolean = num > 0
复制代码
symbol
类型symbol
是 ES6 新增的数据类型,用于表示独一无二的值,只能 Symbol
函数生成。更多内容能够参考:ECMAScript 6 入门 - Symbol。
const sym: symbol = Symbol()
复制代码
事实上,TypeScript 官网上并无详细介绍 symbol
这一基础数据类型。想来缘由有二:
symbol
值只能经过 Symbol()
函数生成,因为类型推断(后面会讲)的存在,无需特别声明变量为 symbol
类型。symbol
的惟一性依赖于底层实现,不太好作 polyfill,因此对于编译 target 低于 ES6 版本的状况,并不推荐使用 symbol
。不过,出于完整性的考虑,这里仍是简要提一下。
undefined
和 null
类型JavaScript 中,undefined
和 null
都被用来表示空值。做为两个原始数据类型,undefined
类型的变量只能被赋值为 undefined
,null
类型的变量只能被赋值为 null
。
// 通常来讲,直接定义一个 undefined 或者 null 类型的变量并无太大意义
let u: undefined = undefined
let n: null = null
复制代码
默认状况下,undefined
和 null
是全部其余类型的子类型。也就是说,若是 undefined
和 null
赋值给任何其余类型的变量。
例如:
let person: string = 'Jerry'
person = null // 有效的
复制代码
然而,若是在 tsconfig
中开启了 strictNullChecks
,那么 undefined
和 null
就只能赋值给 void
或 any
类型变量以及它们自身类型的变量。强烈建议开启这一选项,它能帮助避免不少常见的问题。
undefined
和 null
的关系尽管 undefined
和 null
都表示空值,可是它们本质上是不一样的。undefined
表示变量已声明但未初始化,null
则在逻辑上表示一个空对象指针(这也正是 typeof null === 'object'
的缘由)。
不管什么状况下,都没有必要把一个变量的值显式地设置为
undefined
,但是一样的规则对null
却不适用。换句话说,只要意在保存对象的变量尚未真正保存对象,就应该明确地让该变量保存null
值。 —— Nicholas C.Zakas 《JavaScript 高级程序设计》
void
类型void
类型表示没有任何类型,这句话听起来可能有些自相矛盾。不过,让咱们来考虑这样一种状况:若是一个函数没有返回值,咱们如何表示其类型?这时候 void
类型就派上用场了。这里和 C 语言很像。
function warning(): void {
console.log('WARNING!')
}
复制代码
固然,这里你也能够指定返回值类型为
undefined
。由于 JS 中,若是函数没有返回值,则会默认返回undefind
。不过,使用void
类型可使表意更清晰。
然而,声明一个 void
类型的变量并无太大的用处,由于你只能将其赋值为 null
和 undefined
。
请注意与
void
运算符区分。void
运算符的做用是:对给定的表达式进行求值,而后返回undefined
。若是你从事前端多年,你或许会比较熟悉javascript:void(0);
这样的代码。感兴趣的能够看 这里。
any
类型某种程度上,any
类型就像是 void
类型的反面,任何类型都是 any
类型的子类型。换句话说,any
类型的变量能够被赋予任何类型的值。
let anything: any = "Ohh, that's crazy"
anything = 42
复制代码
对于 any
类型,有两个须要注意的点。
首先,若是变量在声明时,没有声明其类型,也没有初始化(由于类型推断会自动判断类型),那么它会被当作 any
类型。
let something // 等价于 let something: any;
something = 'autochess'
something = 6
复制代码
其次,在 any
类型变量上能够访问任何属性,即便它并不存在。
let something: any = 42
something.mayExist() // 没问题,由于其可能在运行时存在
something.toFixed() // 没问题,虽然确实存在,可是编译器并不会去检查
复制代码
事实上,any
类型是 TypeScript 提供的一个『跳出』方案。对于 any
类型变量,编译器不会作任何类型检查,直接让它们经过类型检查。这在引入第三方库以及将原有 JS 代码改写为 TS 时尤为有用。
不过,注意不要滥用 any
类型。错误地滥用 any
类型会让 TS 失去其存在的意义。
never
类型never
用于表示永远不会存在的值的类型。never
是任何类型的子类型,但没有类型是 never
的子类型。
对于 never
类型,新手理解起来可能比较困难。可是对于 TypeScript 这样一个分析代码流的语言来讲,never
类型是理所固然且必要的。
never
类型经常使用于两种状况:
// 第一种状况
function neverStop(): never {
while (true) {
// do something
}
}
// 第二种状况
function error(message: string): never {
throw new Error(message)
}
复制代码
对于上述两种状况,函数的返回类型都是 never
。
never
类型也能够用作变量的类型注解(例如:let foo: never;
),可是这样作并无什么意义。
下面咱们经过一个例子来学习 never
类型的用法:
function checkNumber(x: string | number): boolean {
if (typeof x === 'number') {
return true
} else if (typeof x === 'string') {
return false
}
return fail('Failure')
}
function fail(message: string): never {
throw new Error(message)
}
复制代码
对于上面的 checkNumber
函数,若是没有 return fail('Failure')
这一句的话,TypeScript 会报错,由于不是全部条件语句都有返回值,当参数 x
既不是 number
也不是 string
时,函数会默认返回 undefined
,然而在严格模式下,undefined
类型与 boolean
类型并不兼容。可是因为 fail
函数返回的 never
类型是 boolean
的子类型,全部上述写法能够经过编译。这也是 never
必须是任何类型的子类型的缘由。
关于 never
类型,这里只是举个例子帮助你们理解。想要真正理解 never
类型,还得结合实战仔细揣摩才行。
本篇文章主要介绍了 TypeScript 中的原始数据类型和几个高级类型。经过这篇文章,相信你们已经能够看出 TypeScript 类型系统的强大和完备。
固然这还不是所有,下篇文章咱们将介绍 TypeScript 中其余几个高级类型:Object
、Array
、Tuple
和 Enum
。敬请期待~