TypeScript——类型

130 阅读5分钟

JavaScript的类型

基本类型

所有的基本类型都是不可变(immutable)的, 不能够被修改, 一切所谓的修改, 其实是替换值,对基本类型API的操作(除了 null 和 undefined),都是对 基本类型的 装箱拆箱操作

类型名称对象
代码
string字符串Stringconst str: string = '请叫我张先森'
number数值Numberconst age: number = 29 // 奔3了, 中年了
boolean布尔Booleanconst isMale: boolean = true // 我是一个男人
bigInt大整型BigIntconst i: bigInt = 9007199254740991n // 我的银行卡余额
symbolSymbolconst 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的遗留问题

  1. 000: object
  2. 1: int
  3. 010: double
  4. 100: string
  5. 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是不会进行安全检查 image.png 指定类型的话会进行检查 image.png

enum

枚举就是把所有的情况都 列出来

enum ColorType {
  red,
  green,
  blue,
  pink
}
const color: ColorType = ColorType.blue

image.png

unknown

unknown 也可以 给予变量任何值,类似 any类型, 但是 TypeScript 会进行安全检查

image.png

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
}

那么这两则有啥区别呢?

  1. 类型扩展
// 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
}

  1. 类型添加新的属性 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
}

image.png

类型操作

属性可选(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' // 报错

image.png

全部属性可选 (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
}

image.png

全部属性只读(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 属性 aliaalienBob 都是 StudentType类型

  1. 一般情况我们会这样写
// 一般情况我们会这样写
type StudentListType = {
  alia: StudentType,
  alien: StudentType,
  Bob: StudentType
}
  1. 使用 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>)

排除 nullundefined

//  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