联合类型表示一个值可以是几种类型之一,使用 | 分隔:
function padLeft(value: string, padding: string | number) {
if (typeof padding === "number") {
return Array(padding + 1).join(" ") + value;
}
if (typeof padding === "string") {
return padding + value;
}
throw new Error(`Expected string or number, got '${padding}'.`);
}
padLeft("Hello", 4);
padLeft("Hello", ">>> ");
交叉类型将多个类型合并为一个类型,使用 & 连接:
interface Person {
name: string;
}
interface Contact {
phone: string;
}
type Employee = Person & Contact;
let employee: Employee = {
name: "Alice",
phone: "123-456-7890"
};
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
function getName(n: NameOrResolver): Name {
if (typeof n === "string") {
return n;
} else {
return n();
}
}
// 类型别名也可以是泛型
type Container = { value: T };
// 类型别名可以引用自己
type Tree = {
value: T;
left?: Tree;
right?: Tree;
};
// 字符串字面量类型
type Easing = "ease-in" | "ease-out" | "ease-in-out";
function animate(dx: number, dy: number, easing: Easing) {
// ...
}
animate(0, 0, "ease-in");
animate(0, 0, "uneasy"); // 错误
// 数字字面量类型
function rollDice(): 1 | 2 | 3 | 4 | 5 | 6 {
return (Math.floor(Math.random() * 6) + 1) as 1 | 2 | 3 | 4 | 5 | 6;
}
function pluck(o: T, propertyNames: K[]): T[K][] {
return propertyNames.map(n => o[n]);
}
interface Car {
manufacturer: string;
model: string;
year: number;
}
let taxi: Car = {
manufacturer: "Toyota",
model: "Camry",
year: 2014
};
let makeAndModel: string[] = pluck(taxi, ["manufacturer", "model"]);
let modelYear = pluck(taxi, ["model", "year"]);
type Readonly = {
readonly [P in keyof T]: T[P];
};
type Partial = {
[P in keyof T]?: T[P];
};
interface Person {
name: string;
age: number;
}
type ReadonlyPerson = Readonly;
type PartialPerson = Partial;
T extends U ? X : Y
// 示例
type TypeName =
T extends string ? "string" :
T extends number ? "number" :
T extends boolean ? "boolean" :
T extends undefined ? "undefined" :
T extends Function ? "function" :
"object";
type T0 = TypeName; // "string"
type T1 = TypeName<"a">; // "string"
type T2 = TypeName; // "boolean"
type Diff = T extends U ? never : T;
type Filter = T extends U ? T : never;
type T1 = Diff<"a" | "b" | "c", "a" | "e">; // "b" | "c"
type T2 = Filter void), Function>; // () => void
在条件类型中推断类型:
type ReturnType = T extends (...args: any[]) => infer R ? R : any;
function f() {
return { x: 10, y: 3 };
}
type P = ReturnType; // { x: number; y: number; }
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"