# 数据类型

  • boolean 布尔值

  • number 数值

  • string 字符串

  • null 空值

  • undefined 未定义

  • Symbol (ES6 中的新类型)

  • 非原始数据类型:

  • 数组 arr: number[] arr: Array

  • Tuple 元祖 x: [string, number]

  • enum 枚举

  • never 永不存在的值的类型

  • void

  • any 任意类型

  • 联合类型

  • void和undefined

# TypeScript类修饰符

TypeScript支持访符 public,private 和 protected,它们决定了类成员的可访问性。

public(公共):所有定义成public的属性和方法都可以在任何地方进行访问。

private(私有):所有定义成private的属性和方法都只能在类定义内部进行访问。

protected(受保护): 该类及其子类的所有成员都可以访问它们。 但是该类的实例无法访问

# type and interface的区别

基本语法与定义范围

  • interface:只能定义对象类型(包括对象的属性、方法等),语法更简洁。
  • type:可以定义任意类型(基本类型、联合类型、交叉类型、函数类型等),适用范围更广。

扩展性(最重要的区别)

  • interface:支持声明合并(自动合并同名接口),且可以被继承。

    // 声明合并:两个同名接口会自动合并
    interface User {
      name: string;
    }
    interface User {
      age: number;
    }
    // 合并后等价于 { name: string; age: number }
    const user: User = { name: "Alice", age: 20 };
    // 继承
    interface Admin extends User {
      role: string;
    }
    const admin: Admin = { name: "Bob", age: 30, role: "admin" };
    
  • type不支持声明合并,也不能被继承,但可以通过交叉类型(&)实现类似扩展效果。

    type User = {
      name: string;
    };
    // 无法合并,会报错
    // type User = { age: number }; 
    
    // 用交叉类型扩展
    type Admin = User & {
      role: string;
    };
    

实现与继承的差异

  • 类实现interfacetype 都可以被类实现,但 type 如果是联合类型则不行。

    interface User {
      name: string;
    }
    
    type Person = {
      age: number;
    };
    
    class Student implements User, Person {
      name: string;
      age: number;
      constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
      }
    }
    
    // 联合类型无法被类实现
    type UnionType = string | number;
    // class Test implements UnionType {} // 报错
    

计算属性

  • 计算属性type 支持计算属性(如映射类型),interface 不支持。

    type Keys = "name" | "age";
    type User = {
      [K in Keys]: string; // 计算属性,仅 type 支持
    };
    

泛型处理

  • 泛型处理:两者都支持泛型,但 interface 在定义泛型对象时更直观。

    // interface 泛型
    interface Box<T> {
      value: T;
    }
    
    // type 泛型
    type Box<T> = {
      value: T;
    };
    

# 数据类型

# 布尔类型

const bool:boolean = true;

# number类型

const num:number = 123;

# string类型

const str:string = '字符串';
// or
const str:string = "字符串";
// or
const str:string = `字符串${变量}`

# array类型

let arr:string[] = ['字符串'];
// or:使用数组泛型
let arr:Array<number> = [1, 2]

# tuple(元组)类型

注意 :表示一个已知元素数量和类型的数组,各元素的类型不必相同

let tupleArr:[number, string, boolean] = [1, '1', true]

# enum(枚举)类型

enum Color {Red, Green, Blue}
let c: Color = Color.Green

# any类型

let a: any = true;
a = 123;
a = '123';

# null & undefined

let num: number | undefined = 123;

# void类型

注意:用于标识方法返回值的类型,表示该方法没有返回值

function hello(): void{
    console.log(123)
}

# never类型

  • 可以赋值给任何类型,代表从不会出现的值。

注意:一般用来指定那些总是抛出异常,无线循环

let a:never;
a = (() => {
    throw new Error('错误')
})()

# object类型

let obj: object = {
    name: '张三',
    age: 20
}

# interface类型

interface a {
    name: string,
    age: number
}
let person: a = {
    name: '张三',
    age: 20
}

继承

interface Animal {
  name: string;
  age: number;
}

interface Dog extends Animal {
  breed: string;
}

let myDog: Dog = {
  name: '旺财',
  age: 3,
  breed: '哈士奇'
};

# typescript高级类型

除基础类型外的高级类型

# 交叉类型(并集)

基本类型交叉

// 同时具有 string 和 number 的特性(实际中这两个原始类型交叉没有意义)
type StringAndNumber = string & number;
// 定义两个接口
interface Printable {
  print: () => void;
}

interface Loggable {
  log: (message: string) => void;
}

// 使用交叉类型组合Printable和Loggable接口
type PrintableAndLoggable = Printable & Loggable;

// 实现一个类,同时具有Printable和Loggable接口的方法
class Logger implements PrintableAndLoggable {
  print() {
    console.log('Printing...');
  }

  log(message: string) {
    console.log(`Logging: ${message}`);
  }
}

// 创建一个Logger实例
const logger = new Logger();
logger.print();
logger.log('Hello, TypeScript!');

注意:在实际开发中,交叉类型通常更适用于组合接口、类型别名等复杂类型。

# 联合类型(交集)

let num: number | string = 123;
// or
function displayData(data: number | string):number | string{
    console.log(data)
    return '123'
}

# 类型别名

类型别名 会给一个类型起个新名字,类型别名有时和接口很像,但是可以作用于原始值,联合类型,元组以及其他任何需要手写的类型

type some = boolean | string;
let str: some = '123';
let bool: some = true

注意:interface只能用于定义对象类型,而type的声明方式除了对象之外,还可以定义交叉,联合,原始类型等,因此,类型声明的方式适用范围更广。

# 类型索引

type User = {
  id: number;
  name: string;
  email: string;
  age: number;
};

// 定义一个类型索引,允许动态访问User对象的属性
type UserKeys = keyof User;

function getUserInfo(user: User, key: UserKeys) {
  return user[key];
}

const user = {
  id: 1,
  name: "Alice",
  email: "alice@example.com",
  age: 30
};

console.log(getUserInfo(user, "name")); // 输出: Alice
console.log(getUserInfo(user, "age")); // 输出: 30

# 类型约束

通过关键字extend进行约束,泛型内使用的主要作用是对泛型加以约束

type baseType = string | number | boolean;
function copy<T extend baseType>(arg: T): T{
	return arg
}
// or 类型约束和类型索引一起使用
function getValue<T,K extend keyof T>(obj: T, key:K):void{
    return obj[key]
}
const obj = {a:1};
const a = getValue(obj, 'a')

# 映射类型

通过in关键字做类型的映射,遍历已有接口的key或者是遍历联合类型。

type User = {
    id: number;
    name: string;
    email: string;
}
type PartialUser = {
    // keyof User:通过类型索引keyof得到联合类型 'id'|'name'|'email'
    // K in keyof User:等同于 k in 'id'|'name'|'email',相当于执行了一次forEach的逻辑,遍历 'id'|'name'|'email'
    [K in keyof User]?: User[K]
}
const person: PartialUser = {
    id: 1,
    name: '123'
}
console.log(person)

# 条件类型

# 对interface的理解

一个接口所描述的是一个对象相关的属性和方法。

本章目录