TypeScript全面指南(二)

以往在 js 中,我们都是对变量进行编程。在 ts 中,我们经常需要对类型进行编程。如果说 TypeScript 是一门对类型进行编程的语言,那么泛型就是这门语言里的(函数)参数。

类型别名(type)中的泛型

type Factory<T> = T | number | string | boolean;

// 带条件类型的使用
type IsEqual<T> = T extends true ? 1 : 2;
type A = IsEqual<true>; // 1
type B = IsEqual<false>; // 2
type C = IsEqual<'reimu747'>; // 2

// 带条件约束,传入的类型必须满足约束
type ResStatus<ResCode extends number> = ResCode extends 200 ? 'success' : 'failure';
type Res1 = ResStatus<200>; // "success"
type Res2 = ResStatus<404>; // "failure"

type Res3 = ResStatus<'10000'>; // 类型“string”不满足约束“number”。

// 多泛型关联
type Conditional<Type, Condition, TruthyResult, FalsyResult> = Type extends Condition ? TruthyResult : FalsyResult;
//  "passed!"
type Result1 = Conditional<'', string, 'passed!', 'rejected!'>;
// "rejected!"
type Result2 = Conditional<'', boolean, 'passed!', 'rejected!'>;

对象类型中的泛型

// 预留出了data的泛型定义,方便以后扩展
interface ResImpl<T = unknown> {
    code: number;
    error?: string;
    data: T;
}

interface DataImpl {
    name: string;
    age: number;
}
const res: ResImpl<DataImpl> = {
    code: 200,
    data: {
        name: 'reimu747',
        age: 18,
    },
};

函数、Class 中的泛型

// 可以方便的进行函数重载
function handle<T>(arg: T | string): T | string {
    if (typeof arg === 'string') {
        return `${arg}${arg}`;
    } else {
        return arg;
    }
}

// 箭头函数的泛型书写方式,为避免和JSX混淆,加上了条件约束
const handle = <T extends any>(input: T): void => {};

Class 中的泛型,基本与函数泛型一致。

内置泛型

// promise
const p = new Promise<number>((resolve, reject) => {
    resolve(200);
});

// array
const arr: Array<number> = [1, 2, 3];
arr.reduce<number>((pre, cur) => pre + cur, 0);

// react
const [state, setState] = useState<number[]>([]);
// 不传入默认值,则类型为 number[] | undefined
const [state, setState] = useState<number[]>();
// 体现在 ref.current 上
const ref = useRef<number>();

TypeScript全面指南(二)
https://www.reimu747.ink/post/20210120_1.html
作者
Reimu747
发布于
2021年1月20日
许可协议