# 70. TypeScript中的类型（上)

### JS中有哪些数据类型

`null`, `undefined`

`string`,`number`, `boolean`

`bigint`, `symbol`

`object`(含`Array`, `Function`,`Date`)

### TS中有哪些数据类型

以上JS中的所有，外加

`void`, `never`, `enum`, `unknown`, `any`

再加上`自定义类型type`，`interface`

### 如何理解TS的数据类型

type number：所有数字的集合，包括整数，小数

type string:

type boolean: true | false(这里的｜是和而不是或)

type Object：{?} | Array | Function | String | Number | Boolean | RegExp |......

### 为什么会有两个number，string，boolean

`number` vs `Number`

区别就是number是用二进制的方式表示数字，new Number(42)是用对象创建数字，其中还包括原型。Number很少用，只有在使用某些函数的时候才会用。

```
let num = 42
num.tofix(2)// 42.00
//既然42是用二进制表示的数字，为什么num.tofix(2)=> 42.00?
//这里明显是使用了new Number
let temp = new Number(42)
value = temp.toFixed(2)
删除temp
value

```

JS中的`Number`， `String`，`Boolean`只用于包装对象，正常开发者不用它们，在TS里也不用

大写的`Object`也不要用，因为表示的范围太大了。所以我们在TS里一般不用`Object`

### 如何在TS里描述对象的数据类型？

1. 用class/constructor描述
2. 用type或interface描述

![截屏2023-05-30 下午11.52.51](https://raw.githubusercontent.com/clairyitinggu/images/main/imgimg202305302353606.png)

```typescript
type A = {
  [k: string]: number //A表示key为string，value为number的所有对象，k可以换成任意单词，如果不是范型用小k，如果是范型用大K，但是一旦到了js，key最后都会变成string，所以上面这样设定没有意义
}
const a: A = {
  age: 18
} 
```

思考题： key的类型可以不是string吗？

答案： 可以，可以换成number， symbol

```typescript
type A = {
 [k: string] : number
}

const a: A = {
	age: 18
}

type A = Record<string, number>

const a: A = {
  age: 18
}
```

结论：由于object太不精确，所以TS开发者一般使用**索引签名**或**Record范型**来描述普通对象。

### 数组对象该怎么描述？

```typescript
type A = string[]  <=> type A = Array<string>
const a: A = ['h', 'i']

type B = number[] <=> type B = Array<number>
const b: B = [42, 0.8]
```

```typescript
type D = [string, string, string]//三元组
const noError: D = ['我','爱','你']//这个是正确的
const error: D = ['h', 'i']//这个是错误的，因为少了一个string
```

```typescript
type E = [string, number]
const e: E = ['小明', 100]
```

```typescript
type F = [string[], number[]]
const f: F = [['柴','米','油','盐'], [1,2,3]]
```

结论：由于Array太不精确，所以TS开发一般用Array\<?>或string\[ ]， 或者\[string, number]来描述数组。

思考题：

```typescript
type A = [1, 2, 3]
const a: A = ?????
```

答案是`[1, 2, 3]`

### 函数对象该怎么描述？

```typescript
type FnA = (a: number, b: number) => number
type FnB = (x: string, y: string) => string
```

⚠️注意，写type的时候可以用 `=>`, 但是写interface的时候不可以。

```typescript
const a: FnA = () =>{
	return 123
}
```

这里没有写参数，为什么可以通过？

答：因为类型兼容。

或者也可以写成

```typescript
const a: FnA = (x, y)=>{
 return 123
}
```

为什么这里不用写type？

答：类型推导

也可以这样写

```typescript
const a: FnA = (x: number, y:number)=>{
	return 123
}
```

上面这个也对，但是多余

```typescript
const a: FnA = (x: number)=>{
	return 123
}
```

上面这个少传一个参数，但是也可以通过。

```typescript
a(1,2)✅
a(1,2,3)❌
```

```typescript
type FnReturnVoid = (s: string) => void//没有返回值
type FnReturnUndefined = (s: string) = undefined//不会有人写这个

const v: FnReturnVoid = (s: string) => {
  console.log(s)
}

const u: FnReturnUndefined = (s: string) => {
  console.log(s)
  return undefined
}
```

箭头函数的缺点： 不支持this

方方老师关于`this`的文章：<https://zhuanlan.zhihu.com/p/23804247>

```typescript
type Person = {name: string, age: number}
type FnWithThis = (this: Person, name: string) => void
const sayHi: FnWithThis = function(name){
	console.log("hi" + this.name)
}
sayHi("Jack")
//The 'this' context of type 'void'
//is not assignable to method's 'this'
//of type 'Person'
```

结论：

由于Function太不精确，所以TS开发者一般用`( )=>?`来描述函数

其他对象一般直接用class描述

### any, unknown，never是什么？
