JavaScript的类型
基本类型
所有的基本类型都是不可变(immutable)的, 不能够被修改, 一切所谓的修改, 其实是替换值,对基本类型API的操作(除了 null 和 undefined),都是对 基本类型的 装箱 和 拆箱操作
| 类型 | 名称 | 对象 | 代码 |
|---|---|---|---|
| string | 字符串 | String | const str: string = '请叫我张先森' |
| number | 数值 | Number | const age: number = 29 // 奔3了, 中年了 |
| boolean | 布尔 | Boolean | const isMale: boolean = true // 我是一个男人 |
| bigInt | 大整型 | BigInt | const i: bigInt = 9007199254740991n // 我的银行卡余额 |
| symbol | Symbol | const s: symbol = Symbol('a') // Symbol 不能 new | |
| null | 对象 | const s: null = null // typeof null === 'object' | |
| undefined | 未定义 | const s: undefined = undefined |
null
typeof null === 'object'并不代表 null 是一个对象, 而是js的遗留问题
- 000: object
- 1: int
- 010: double
- 100: string
- 110: boolean 而 null 全是 0, 所以在typeof 的时候, 认为 null 就是一个对象
引用类型
| 类型 | 名称 | 代码 |
|---|---|---|
| Array | 数组 | const arr: Array<string> = ['a','b']; |
| Object | 对象 | const obj: Object = new Object() // 你还有对象吗? |
| Function | 函数 | const fn: Function = () => {} // 我是一个男人 |
TypeScript 新增的类型
any
一旦 一个变量是 any类型, 那么TypeScript不会进行类型检查,
let obj: any = { x: 0 }
obj = 'hello'
obj = 1
obj.func()
TypeSript是不会进行安全检查
指定类型的话会进行检查
enum
枚举就是把所有的情况都 列出来
enum ColorType {
red,
green,
blue,
pink
}
const color: ColorType = ColorType.blue
unknown
unknown 也可以 给予变量任何值,类似 any类型, 但是 TypeScript 会进行安全检查
never
顾名思义,函数永远不会返回值, 比如 函数 抛出异常 , 死循环
function fail(msg: string): never {
throw new Error(msg);
}
function fail(msg: string): never {
while(true){}
}
联合类型
所谓的联合类型就是, 几种类型的结合;比如你在获取后台接口返回的用户信息的时候, 有一个年龄字段,那么 后台接口可能会返回 数值字符串 或者 数值, 你不可能对不同情况 定义不同的变量, 此时 联合类型的作用就出来了
let age: number | string
age = 1
age = '1'
自定义类型(类型别名)
定义一个属于你自己专属的类型, 简化代码
type ageType = number | string
let age: ageType
function getAge(age: ageType): ageType {
return age
}
接口类型
enum SexEnum {
male,
female
}
interface personType {
name: string;
age: string | number;
sex: SexEnum
}
const p: personType = {
name: '请叫我张先森',
age: 12,
sex: SexEnum.female
}
你会发现 好像 type 也可以 实现这样的类型定义
enum SexEnum {
male,
female
}
type personType = {
name: string;
age: string | number;
sex: SexEnum;
}
const p: personType = {
name: '请叫我张先森',
age: 12,
sex: SexEnum.female
}
那么这两则有啥区别呢?
- 类型扩展
// interface
enum SexEnum {
male,
female
}
interface personType {
name: string;
age: string | number;
sex: SexEnum;
}
interface studentType extends personType {
school: string
}
const student: studentType = {
name: '请叫我张先森',
age: 29,
sex: SexEnum.male,
school: '中国加利墩大学'
}
// type
type personType {
name: string;
age: string | number;
sex: SexEnum;
}
type studentType = personType & {
school: string
}
- 类型添加新的属性 interface 可以出现重复定义,实现新增属性, 而 type 不可以, 出现同名称 提示报错
// interface
enum SexEnum {
male,
female
}
interface personType {
name: string;
age: string | number;
sex: SexEnum;
}
interface personType {
address: string
}
const student: personType = {
name: '请叫我张先森',
age: 29,
sex: SexEnum.male,
address: '江苏南京'
}
enum SexEnum {
male,
female
}
// 报错 标志符号 personType 重复
type personType = {
name: string;
age: string | number;
sex: SexEnum;
}
type personType = {
address: string
}
类型操作
属性可选(optional)
在自定义类型的时候, 所有的属性都是 required, 如果在属性后面 添加 ? 则会变成 optional 可选 类型
enum SexEnum {
male,
female
}
interface personType {
name: string;
age: string | number;
sex: SexEnum;
school?: string // 可选类型
}
const student: personType = {
name: '请叫我先森',
age: 29,
sex: SexEnum.male
}
属性只读(readonly)
属性只读 ,在属性前面添加 readonly; 属性初始化后, 不能重新赋值
interface personType {
readonly name: string;
}
const p: personType = {
name: '请叫我张先森'
}
p.name = 'hha' // 报错
全部属性可选 (Partial<Type>)
将现有的类型中的所有属性转为 可选属性, 组成新的类型
enum SexEnum {
male,
female
}
interface personType {
name: string;
age: string | number;
sex: SexEnum;
school?: string
}
const student: Partial<personType> = {
}
全部属性必选(Required<Type>)
将现有的类型中的所有属性转为 必选属性, 组成新的类型
enum SexEnum {
male,
female
}
interface personType {
name: string;
age: string | number;
sex: SexEnum;
school?: string
}
// 报错, 缺少属性 school
const student: Required<personType> = {
name: '请叫我张先森',
age: 29,
sex: SexEnum.male
}
全部属性只读(Readonly<Type>)
将现有的类型中的所有属性转为 只读属性, 组成新的类型
interface personType {
name: string;
age: string | number
}
const p: Readonly<personType> = {
name: '请叫我张先森',
age: 12
}
p.name = 'hha' // 报错
p.age = 12 // 报错
选择部分属性(Pick<Type, Keys>)
从现有的类型中,选择 部分类型, 组成新的类型
enum SexEnum {
female,
male
}
interface personType {
name: string;
age: string | number,
sex: SexEnum
}
const p: Pick<personType, 'age' | 'name'> = {
name: '请叫我张先森',
age: 12
}
键值同一类型(Record<Keys, Type>)
对象中的所有属性 都是 同一个类型
interface StudentType {
name: string,
age: number | string
}
有一个对象 students 属性 alia, alien, Bob 都是 StudentType类型
- 一般情况我们会这样写
// 一般情况我们会这样写
type StudentListType = {
alia: StudentType,
alien: StudentType,
Bob: StudentType
}
- 使用 Record<Keys, Type> 显然变得很简单了
// Record<Keys, Type>
type StudentListType = Record<'alia' | 'alien' | 'Bob',StudentType >
const students: StudentListType = {
alia: { name: 'alia', age: 12},
alien: { name: 'alien', age: 14},
Bob: { name: 'Bob', age: 24},
}
排除部分属性(Omit<Type, keys>)
interface StudentType {
name: string,
age: number | string,
school: string,
sex: string
}
type PersonType = Omit<StudentType, 'school'|'sex' >
/**
* type PersonType = {
* name: string,
* age: number | string
* }
*/
从联合类型中选择部分类型(Extract<Type, ExcludedUnion>)
// type t = string
type t = Extract<string | number | boolean, string >
从联合类型中排除部分类型(Exclude<Type, ExcludedUnion>)
//type t = number | boolean
type t = Exclude<string | number | boolean, string >
提取非空类型(NonNullable<Type>)
排除 null 和 undefined
// type t = string | number
type t = NonNullable<string | number | null | undefined >
从函数类型的参数中生成类型 (Parameters<Type>)
function getUser(name: string, age: string): void {}
// type functionType = [name: string, age: string ]
type functionType = Parameters<typeof getUser>
或者
// type functionType = [name: string, age: string ]
type func = (name: string, age: string) => void
type functionType = Parameters<func>
从函数返回类型生成类型 (ReturnType<Type>)
// type functionType = {rname: string, rage: number}
type func = (name: string, age: string) => {rname: string, rage: number}
type functionType = ReturnType<func>
从构造函数参数生成类型(ConstructorParameters<Type>)
// type functionType = [name: string, age: string ]
declare class StudentClass {
constructor(name: string, age: number);
}
type functionType = ConstructorParameters<typeof StudentClass>
从现有的对象中提取类型 typeof
enum SexEum {
female,
male
}
const student = {
name: '叫我张先森',
age: 12,
sex: SexEum.male
}
/***
* type StudentType {
* name: string;
* age: number;
* sex: SexEum
* }
*/
type StudentType = typeof student