返回介绍

条件类型基础

发布于 2024-09-11 00:55:49 字数 2603 浏览 0 评论 0 收藏 0

条件类型的语法类似于平时常用的三元表达式:

ValueA === ValueB ? Result1 : Result2;
TypeA extends TypeB ? Result1 : Result2;

条件类型中使用 extends 判断类型的兼容性,而非判断类型的全等性。在类型层面中,对于能够进行赋值操作的两个变量,并不需要它们的类型完全相等,只需要具有兼容性,而两个完全相同的类型,其 extends 自然也是成立的。

条件类型绝大部分场景下会和泛型一起使用,泛型参数的实际类型会在实际调用时才被填充,而条件类型在这一基础上,可以基于填充后的泛型参数做进一步的类型操作。

type LiteralType<T> = T extends string ? 'string' : 'other';

type Res1 = LiteralType<'wangxiaobai'>; // "string"
type Res2 = LiteralType<18>; // "other"

条件类型中也常见多层嵌套,如:

export type LiteralType<T> = T extends string
    ? 'string'
    : T extends number
    ? 'number'
    : T extends boolean
    ? 'boolean'
    : T extends null
    ? 'null'
    : T extends undefined
    ? 'undefined'
    : never;

type Res1 = LiteralType<'wangxiaobai'>; // "string"
type Res2 = LiteralType<18>; // "number"
type Res3 = LiteralType<true>; // "boolean"

在函数中,条件类型与泛型的搭配同样很常见。

function universalAdd<T extends number | bigint | string>(x: T, y: T) {
    return x + (y as any);
}

当调用这个函数时,由于两个参数都引用了泛型参数 T ,因此泛型会被填充为一个联合类型:

universalAdd(18, 1); // T 填充为 18 | 1
universalAdd('wangxiaobai', '18'); // T 填充为 'wangxiaobai' | '18'

此时的返回值类型就需要从这个字面量联合类型中推导回其原本的基础类型。

同一基础类型的字面量联合类型可以被认为是此基础类型的子类型,即 18 | 1 是 number 的子类型。

因此可以使用嵌套的条件类型来进行字面量类型到基础类型地提取:

function universalAdd<T extends number | bigint | string>(
    x: T,
    y: T
): LiteralToPrimitive<T> {
    return x + (y as any);
}

export type LiteralToPrimitive<T> = T extends number
    ? number
    : T extends bigint
    ? bigint
    : T extends string
    ? string
    : never;

universalAdd('wangxiaobai', '18'); // string
universalAdd(18, 1); // number
universalAdd(10n, 10n); // bigint

条件类型还可以用来对更复杂的类型进行比较,比如函数类型:

type Func = (...args: any[]) => any;

type FunctionConditionType<T extends Func> = T extends (
  ...args: any[]
) => string
  ? 'A string return func!'
  : 'A non-string return func!';

//  "A string return func!"
type StringResult = FunctionConditionType<() => string>;
// 'A non-string return func!';
type NonStringResult1 = FunctionConditionType<() => boolean>;
// 'A non-string return func!';
type NonStringResult2 = FunctionConditionType<() => number>;

条件类型用于判断两个函数类型是否具有兼容性,而条件中并不限制参数类型,仅比较二者的返回值类型。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文