TypeScript 类型(笔记)

32 阅读4分钟

类型复用

复用type定义的类型

type Point = {
  x: number;
  y: number;
};

type Coordinate = Point & {
  z: number;
};

复用interface定义的类型

interface Point {
  x: number;
  y: number;
};

interface Coordinate extends Point {
  z: number;
}

interface复用type定义的类型

type Point = {
  x: number;
  y: number;
};

interface Coordinate extends Point {
  z: number;
}

type复用interface定义的类型

interface Point {
  x: number;
  y: number;
};

type Coordinate = Point & {
  z: number;
};

属性复用时排除、选择

剔除属性C,利用TypeScript提供的工具类型Omit来更高效地实现这种复用

interface Props {
  a: string;
  b: string;
  c: string;
}

interface Props1 extends Omit<Props, 'c'> {
  e: string;
}

工具类型Pick也可以用于实现此类复用

interface Props {
  a: string;
  b: string;
  c: string;
}

interface Props1 extends Pick<Props, 'a' | 'b'> {
  e: string;
}

使用组件库的基础类型

通过基础类型延伸其它类型

type Size = 'small' | 'middle' | 'large';
type BaseProps<T> = {
  className?: string;
  visible?: boolean;
  size?: Size;
  defaultValue?: T;
}

//具体组件的属性类型
interface WInputProps extends BaseProps<string> {
  maxLength?: number;
  showCount?: boolean;
}

处理含有不同类型元素的数组

元组是处理这种情况的理想选择

function useMyHook(): [string, number] {
  return ['示例文本', 42];
}

function MyComponent() {
  const [text, number] = useMyHook();
  console.log(text);  // 输出字符串
  console.log(number);  // 输出数字
  return null;
}

处理参数数量和类型不固定的函数

这正是函数重载发挥作用的场景

function greet(name: string): string;
function greet(age: number): string;
function greet(value: any): string {
  if (typeof value === "string") {
    return `Hello, ${value}`;
  } else if (typeof value === "number") {
    return `You are ${value} years old`;
  }
}

箭头函数,不支持重载,实现

type GreetFunction = {
  (name: string): string;
  (age: number): string;
};

const greet: GreetFunction = (value: any): string => {
  if (typeof value === "string") {
    return `Hello, ${value}`;
  } else if (typeof value === "number") {
    return `You are ${value} years old.`;
  }
  return '';
};

组件属性定义:使用type还是interface?

由于同名接口会自动合并,而同名类型别名会冲突,我推荐使用interface定义组件属性。这样,使用者可以通过declare module语句自由扩展组件属性,增强了代码的灵活性和可扩展性。

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

const userInfo: UserInfo = { name: "张三", age: 23 };

Partial、Required

Partial用于将给定类型的所有属性设置为可选。换句话说,Partial 可以创建一个新的类型,该类型具有与原始类型相同的属性,但是这些属性都是可选的。 Required 用于将给定类型的所有属性设置为必需的。换句话说,Required 可以创建一个新的类型,该类型具有与原始类型相同的属性,但是这些属性都是必需的,不能省略。

interface User {
  name: string;
  age: number;
  email: string;
}

function updateUser(user: Partial<User>): void {
  // 更新用户信息
  // ...
}


interface User {
  name?: string;
  age?: number;
  email?: string;
}

function createUser(user: Required<User>): void {
  // 创建用户
  // ...
}

Readonly

Readonly用于将给定类型的所有属性设置为只读。换句话说,Readonly 可以创建一个新的类型,该类型具有与原始类型相同的属性,但是这些属性都是只读的,不能被修改。

interface User {
  readonly name: string;
  readonly age: number;
  readonly email: string;
}

function getUser(): Readonly<User> {
  return { name: "John", age: 30, email: "john@example.com" };
}

Record

Record 用于创建一个具有指定属性类型的对象类型。Record 接受两个类型参数,第一个参数指定属性的名称,第二个参数指定属性的类型。

type Fruit = "apple" | "banana" | "orange";
type Price = number;

const fruitPrices: Record<Fruit, Price> = {
  apple: 1.5,
  banana: 0.5,
  orange: 0.8,
};

console.log(fruitPrices.apple); // 1.5
console.log(fruitPrices.banana); // 0.5
console.log(fruitPrices.orange); // 0.8

Exclude、Extract

Exclude 用于从一个联合类型中排除指定的类型。 Extract 用于从一个联合类型中提取指定的类型。

type Animal = "dog" | "cat" | "bird";
type ExcludeBird = Exclude<Animal, "bird">;

const myPets: ExcludeBird[] = ["dog", "cat"];

type ExtractBird = Extract<Animal, "bird">;

const myBird: ExtractBird = "bird";

Parameters

Parameters 是一个泛型工具类型,它用于获取函数类型 T 的参数类型。它接受一个函数类型作为参数,并返回一个元组类型,其中包含了函数的每个参数类型。

function greet(name: string, age: number): void {
  console.log(`Hello, ${name}! You are ${age} years old.`);
}
type GreetParams = Parameters<typeof greet>;
// GreetParams 的类型为 [string, number]

ConstructorParameters

ConstructorParameters 用于获取构造函数的参数类型。

class Person {
  constructor(name: string, age: number) {
    // constructor implementation
  }
}

type PersonConstructorParams = ConstructorParameters<typeof Person>;

const params: PersonConstructorParams = ["John", 25];

ReturnType

ReturnType是一个泛型工具类型,它用于获取函数类型T的返回值类型。它接受一个函数类型作为参数,并返回该函数的返回值类型。

function add(a: number, b: number): number {
  return a + b;
}
type AddResult = ReturnType<typeof add>;

InstanceType

InstanceType 用于获取构造函数的实例类型。

class Person {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  sayHello() {
    console.log(`Hello, my name is ${this.name} and I'm ${this.age} years old.`);
  }
}

type PersonInstance = InstanceType<typeof Person>;

const person: PersonInstance = new Person("John", 25);
person.sayHello();

vue 增加window属性类型

修改:shims-vue.d.ts

// ...
interface Window {
  appBaseUrl: string;
  appType: string;
  appName: string;
}

TypeScript 内置类型

// 基本的原始类型
// number、string、boolean、null和 undefined

// 高级的内置类型
// Array、Tuple、Enum和 Any
// Tuple类型用于定义具有固定长度和特定类型的数组


// 复杂的内置类型
// Object、Function 和 Promise
// Object 类型用于描述非原始类型的变量
// Function 类型用于描述函数
// Promise 类型用于处理异步操作的结果。


// 有用的内置类型
// Date、RegExp 和 Error


// 类型推断
// union、intersection、type assertion 和 type inference