Type Basic#
// basic syntax
type someType = somePrimitives | Object;
const val: someType = someValue;
// interface
interface Foo {
[x: any]: someType;
}
// foo-class.d.ts
/**
* .d.ts 不会产生具体的代码实体, 使用 declare 关键字,且不要使用 export 语句
* 如果使用了 export,该文件就会变成实体 ts 文件,不会被 ts 的自动类型解析所识别,只能通过 import 使用
*/
declare class FooClass {
someProp: someType;
someMethod(someArgs: someType): someType;
}
Type VS Interface#
type[1] 写法是比较推崇的
类比来看,interface 是一种声明(statement),而 type 是一种表达式(expression)
interface类似于c 中的struct写法,用于声明object的类型
type FooBar = {
foo: Foo
bar: Bar
}
// 👍 base type
// ❌ 对于interface来说,不能定义基础类型,必须是一个Object Based;
type BaseType = string
interface IBase = string // 💣报错
interface IFooBar {
foo: Foo
bar: Bar
}
// 👍 union type,interface 做不到
type UnionType = string | number
// ❌ 如果重新定义了 IFooBar,TS不会提示,而是会属性合并;
// 👍 如果用Type写法,TS会报错:重复定义
interface Window {
test: string
}
window.test = "interface bad feature"; // Bad
// 👍 combined type
type FooBarCombined = { foo: Foo } & { bar: Bar } & { fooBar: FooBar }
// equals
interface IFoo {
foo: Foo
}
interface IBar {
bar: Bar
}
interface IFoobarCombined extends IFoo,IBar {
fooBar: FooBar
}
Type Predicates#
type Employee = { name: string, email: string }
type UserOrEmployee = { name: string } | Employee;
const people: UserOrEmployee[] = [
//...
];
people.forEach(person => {
if (isEmployee(person)) {
console.log(person.email); // 不进行type predicates,则💣报错
}
})
// function isEmployee(person: UserOrEmployee) {
function isEmployee(person: UserOrEmployee): person is Employee {
return "email" in person;
}
Advance#
Example 1: narrow types#
const INVALID_STATUS = ["deleted", "rejected"] as const;
type InvalidStatus = (typeof INVALID_STATUS)[number];
type ValidStatus = "pending" | "in_progress" | "done";
type Status = InvalidStatus | ValidStatus;
// Type Predicates
function isInvalidStatus(status: Status): status is InvalidStatus {
return INVALID_STATUS.includes(status);
}
function getTaskDesc(task: Task): string {
// 优化值判断的面条代码
// if (task.status === "deleted" || task.status === "rejected")
if (isInvalidStatus(task.status) {
return `Task ${task.id} is Invalid!`;
}
return getValidTaskDesc(task.status);
}
function getValidTaskDesc(status: ValidStatus) {
// switch case expression
}
Example 2: TS check#
type Status = ...;
// const TYPE_BY_STATUS: Record<string, string> = {
const TYPE_BY_STATUS: Record<Status, string> = {
deleted: "Deleted",
// rest
}
Exan