TypeScript全解:类型(上)
JS/TS 中有哪些数据(data)类型(type)
- JS
- null, undefined, string, number, boolean, bigint, symbol, obejct(含 Array、Function、Date…)
- TS
- 以上所有,加上 void, never, enum, unknown, any,再加上自定义类型 type, interface
如何理解 TS 的数据类型
和 JS 的区别在于,JS 说到数据类型的时候,是说这个值是字符串,这个值就是数字,
那么 TS 呢,指的是一类数据的类型,而不是一个,所以说得从集合的角度来理解
例如:
- number 是指 1 | 1.1 | 1.2 | …. | 2 | …
- string 是指 a | b | … | z | …
- boolean 是指 true | false
- Object 是指 {…} | Array | Function | String | Number | … | RegExp | …
注意:Object 这里 为什么还会有 String,Number?
这里涉及到 JS 的历史遗留知识,42 VS new Number(42)
基本没有人会用 new Number(42) 来表示“42”
42 就是一个普通的值
而 new Number(42),则表示这是一个对象:
1
2
3
4
5
6
7
8 {
constructor: ....,
toFixed: ...,
toString: ...,
valueOf: function() {
return 42
}
}但是 (42).toFixed(),为什么可以正常运行,明显不合逻辑
当然是因为 JS 的包装对象,在你写上述代码的时候,JS 帮你做了这四步:
- let temp = new Number(42); 2. value = temp.toFixed(2); 3. 删除 temp; 4. 返回 value;
所以 JS 中的 Number, String, Boolean 只用于包装对象,正常来说不会用到他们,当然在 TS 里也不用
那么问题又来了,
var n = 42; n.xxx = 2; console.log(n.xxx)
,会打印出什么呢?
用类型签名和Rercord描述对象
1 | type A = Object |
这和 any 有什么区别嘛,所以我们一般在 TS 里不用 Object
那么用什么呢?
- 用 class / constructor 描述,例如:
const a: Function = () => {}
- 用 type 或 interface 描述,例如:
type Person = { name: string; age: number; }
,我们比较常用的是索引签名type A = { [k: string]: number }
(这个语法特别丑),所以我们一般用Record<string, number>
思考:key 的类型可以不是 string/symbol 吗?
试一下就知道了
1 | type A = Record<number, number> |
当 key 的类型是 number 的时候,虽然 js 不支持,但 ts 只会做字面量上的检查
用[]和Array泛型来描述数组对象
1 | type A = string[] |
思考
1 | type A = [1,2,3] |
只能为 [1,2,3],注意这里的 type A 不是值,1 也是类型,是 number 的子集
描述函数对象
1 | type FnA = (a, number, b: number) => number |
返回值为 void 和 undefined 的时候
1 | type FnA = () => void |
所以在实践中,我们的函数没有返回值,我们一般写 void
怎么描述函数的 this
1 | // 这里名称必须为 this |
由于 Function 不够精确,所以 TS 开发者一般用
() => ?
来描述函数
其他对象一般直接用 class 来描述
其他对象
1 | const d: Date = new Date() |
any、unknown 是什么?
any 更像是所有的值的集合(也不准确),unknown 和 any 差不多,只是你不收窄类型你就无法使用
在官方文档中 any 的解释为如果你不想让你的类型报错你可以使用这个类型
never 是什么
可以理解为空集,哪有什么用呢?用来做检查
1 | type A = string & number |