跳到主要内容

补充

函数类型

function greeter(fn: (a: string) => void) {
fn("Hello, World");
}

function printToConsole(s: string) {
console.log(s);
}

greeter(printToConsole);
可选参数
function f(x?: number) {
// ...
}
构造函数
interface CallOrConstruct {
new (s: string): Date;
(n?: number): string;
}
function fn(ctor: CallOrConstruct) {
return new ctor("hello");

// 或者返回不带new 的属性
// return ctor(1);
}
添加泛型作为类型参数
function firstElement<Type>(arr: Type[]): Type | undefined {
return arr[0];
}
合理使用length属性
function longest<Type extends { length: number }>(a: Type, b: Type) {
if (a.length >= b.length) {
return a;
} else {
return b;
}
}
rest更多参数
function multiply(n: number, ...m: number[]) {
return m.map((x) => n * x);
}
// 'a' gets value [10, 20, 30, 40]
const a = multiply(10, 1, 2, 3, 4);

数组类型

ReadonlyArray数组属性是只读的
function doStuff(values: ReadonlyArray<string>) {
// We can read from 'values'...
const copy = values.slice();
console.log(`The first value is ${values[0]}`);

// ...but we can't mutate 'values'.
values.push("hello!"); // Property 'push' does not exist on type 'readonly string[]'.

// 直接修改数组可以,但不能直接修改属性
values = ['abc']; // ok
}

// 报错:'ReadonlyArray' only refers to a type, but is being used as a value here.
new ReadonlyArray("red", "green", "blue");
readonly数组属性是只读的
function doStuff(values: readonly string[]) {
// We can read from 'values'...
const copy = values.slice();
console.log(`The first value is ${values[0]}`);

// ...but we can't mutate 'values'.
values.push("hello!"); // Error: Property 'push' does not exist on type 'readonly string[]'.
}

let x: readonly string[] = [];
let y: string[] = [];

x = y; // 直接赋值数组可以
x[0]='1'; // Error: 直接修数组属性不行
y = x; // Error: 只读属性不能分配给string[]可变属性

对象类型

使用type别名
type Person = {
name: string;
age: number;
};
使用interface接口
interface Person {
name: string;
age: number;
}
可选属性
interface SquareConfig {
color: string;
width?: number;
}
只读属性
interface SomeType {
readonly prop: string;
}
type SomeType2 = {
readonly prop: string;
}
只定义属性名类型,不定义具体属性名
interface StringArray {
[index: number]: string;
}

interface NumberDictionary {
[index: string]: number;
length: number; // ok
name: string; // Property 'name' of type 'string' is not assignable to 'string' index type 'number'.
}

interface NumberOrStringDictionary {
[index: string]: number | string;
length: number; // ok, length is a number
name: string; // ok, name is a string
}

interface ReadonlyStringArray {
readonly [index: number]: string;
}

interface SquareConfig {
color?: string;
width?: number;
[propName: string]: any;
}
extends扩展属性
interface AddressWithUnit extends BasicAddress {
unit: string;
}

// 扩展多个
interface Colorful {
color: string;
}
interface Circle {
radius: number;
}
interface ColorfulCircle extends Colorful, Circle {}
const cc: ColorfulCircle = {
color: "red",
radius: 42,
};

由类型生成新类型

1.使用泛型

函数中的类型参数
function identity<Type>(arg: Type): Type {
return arg;
}

let myIdentity: <Type>(arg: Type) => Type = identity;

// 泛型接口
interface GenericIdentityFn<Type> {
(arg: Type): Type;
}
function identity<Type>(arg: Type): Type {
return arg;
}
let myIdentity: GenericIdentityFn<number> = identity;
class中使用泛型
class GenericNumber<NumType> {
zeroValue: NumType;
add: (x: NumType, y: NumType) => NumType;
}
泛型中使用extends
function createInstance<A extends Animal>(c: new () => A): A {
return new c();
}

2.keyof获取属性名类型组成联合类型

type Arrayish = { [n: number]: unknown };
type A = keyof Arrayish; // number

3.typeof获取返回值类型组成联合类型

let s = "hello";
let n: typeof s; // string

3.索引类型

对象的索引
type Person = { age: number; name: string; alive: boolean };

// 单索引
type Age = Person["age"]; // number

// 多索引 - 联合类型
type I1 = Person["age" | "name"]; // string | number
type AliveOrName = "alive" | "name";
type I3 = Person[AliveOrName]; // boolean | string

// 多索引 - keyof
type I2 = Person[keyof Person]; // string | number | boolean
数组的索引
const MyArray = [
{ name: "Alice", age: 15 },
{ name: "Bob", age: 23 },
{ name: "Eve", age: 38 },
];

// Array[number]在ts中表示数组元素;typeof获取类型的返回值
type Person = typeof MyArray[number]; // { name: string; age: number; }

type Age = typeof MyArray[number]["age"]; // number
type Age2 = Person["age"]; // number

4.条件类型

interface Animal {
live(): void;
}
interface Dog extends Animal {
woof(): void;
}

type Example1 = Dog extends Animal ? number : string; // number

type Example2 = RegExp extends Animal ? number : string; // string
条件类型中使用infer类型推断
type Flatten<Type> = Type extends Array<infer Item> ? Item : Type;

type GetReturnType<Type> = Type extends (...args: never[]) => infer Return
? Return
: never;
type Num = GetReturnType<() => number>; // number
type Str = GetReturnType<(x: string) => string>; // string
type Bools = GetReturnType<(a: boolean, b: boolean) => boolean[]>; // boolean[]

5.映射类型

索引签名用于声明尚未提前声明的属性类型
type OnlyBoolsAndHorses = {
[key: string]: boolean | Horse;
};

const conforms: OnlyBoolsAndHorses = {
del: true,
rodney: false,
};
泛型
type OptionsFlags<Type> = {
[Property in keyof Type]: boolean;
};
移除属性的只读状态(-readonly)
type CreateMutable<Type> = {
-readonly [Property in keyof Type]: Type[Property];
};

type LockedAccount = {
readonly id: string;
readonly name: string;
};

type UnlockedAccount = CreateMutable<LockedAccount>; // { id: string, name: string }
移除属性的可选状态(-?)
type Concrete<Type> = {
[Property in keyof Type]-?: Type[Property];
};

type MaybeUser = {
id: string;
name?: string;
age?: number;
};

type User = Concrete<MaybeUser>; // { id: string;name: string;age: number; }
使用as重写属性名
type Getters<Type> = {
[Property in keyof Type as `get${Capitalize<string & Property>}`]: () => Type[Property]
};

interface Person {
name: string;
age: number;
location: string;
}

type LazyPerson = Getters<Person>; // { getName: () => string;getAge: () => number;getLocation: () => string; }
使用as+Exclude过滤属性
type RemoveKindField<Type> = {
[Property in keyof Type as Exclude<Property, "kind">]: Type[Property]
};

interface Circle {
kind: "circle";
radius: number;
}

type KindlessCircle = RemoveKindField<Circle>; // { radius: number; }
使用as+索引类型重写属性名
type EventConfig<Events extends { kind: string }> = {
[E in Events as E["kind"]]: (event: E) => void;
}

type SquareEvent = { kind: "square", x: number, y: number };
type CircleEvent = { kind: "circle", radius: number };

type Config = EventConfig<SquareEvent | CircleEvent> // { square: (event: SquareEvent) => void; cirle: (event: CircleEvent) => void;}

6.使用模板字符串

字符串
type World = "world";

type Greeting = `hello ${World}`; // "hello world"
字符串组成的联合类型
type EmailLocaleIDs = "welcome_email" | "email_heading";
type FooterLocaleIDs = "footer_title" | "footer_sendoff";

type AllLocaleIDs = `${EmailLocaleIDs | FooterLocaleIDs}_id`; // "welcome_email_id" | "email_heading_id" | "footer_title_id" | "footer_sendoff_id"

type Lang = "en" | "ja" | "pt";

type LocaleMessageIDs = `${Lang}_${AllLocaleIDs}`; // "en_welcome_email_id" | "en_email_heading_id" | "en_footer_title_id" | "en_footer_sendoff_id" | "ja_welcome_email_id" | "ja_email_heading_id" | "ja_footer_title_id" | "ja_footer_sendoff_id" | "pt_welcome_email_id" | "pt_email_heading_id" | "pt_footer_title_id" | "pt_footer_sendoff_id"

7.类型工具

  • Record<K, T>: 创建一个以类型 K 为键,类型 T 为值的对象类型。
  • Readonly<T>: 创建只读版本的类型。
  • Partial<T>: 复制T类型的所有属性,并将所有属变成可选属性
  • Required<T>: 复制T类型的所有属性,并将所有属变成必选属性
  • Pick<T, K>: 子集,从类型 T 中选取指定属性 K
  • Omit<T, K>: 排除,从类型 T 中排除属性 K
  • Exclude<T, U>: 从类型 T 中排除可以赋值给类型 U 的类型。
  • ReturnType<T>: 获取函数类型 T 的返回类型。
  • Union: 用于创建联合类型,例如 number | string。的关系
  • Intersection: 用于创建交叉类型,表示同时具有多个类型的值。的关系

8.字符串操作类型

  • Uppercase: 转大写
  • Lowercase: 转小写
  • Capitalize: 首字母转大写
  • Uncapitalize: 首字母转小写

重载函数

重载版本的函数签名

  • 函数体之前的,每个版本对应不同的参数和返回值类型
  • 最后的通用实现部分(即函数体)必须能够处理所有可能的参数类型,通常使用联合类型或条件类型来实现
  • 用于处理一些复杂的情况,例如函数根据传递的参数类型来决定不同的逻辑。它们能够提供更好的类型检查和类型推断,从而增加代码的安全性和可读性
function greet(name: string): string;
function greet(age: number): string;
function greet(input: string | number): string {
if (typeof input === "string") {
return `Hello, ${input}!`;
} else if (typeof input === "number") {
return `You are ${input} years old.`;
}
return "Hello!";
}

console.log(greet("Alice")); // Hello, Alice!
console.log(greet(25)); // You are 25 years old.
console.log(greet(true)); // Error: Argument of type 'boolean' is not assignable to parameter of type 'string | number'.

其它

1.Parameters

用于从函数类型中获取参数类型的元组类型

type MyFunction = (a: number, b: string, c: boolean) => void;

type MyFunctionParameters = Parameters<MyFunction>; // [number, string, boolean]

2.const类型断言中的字面量类型

const myNumber = 42;
const myLiteralNumber = 42 as const; // 类型为 42(数字字面量类型)

const myString = "hello";
const myLiteralString = "hello" as const; // 类型为 "hello"(字符串字面量类型)