TypeScript系列教程九《类型转换》-- 条件类型(1)

使用条件类型,改造重载的createLabel 函数并使用。

interface IdLabel {

id: number /* some fields */;

}

interface NameLabel {

name: string /* other fields */;

}

type NameOrId<T extends number | string> = T extends number

? IdLabel
NameLabel;

function createLabel<T extends number | string>(idOrName: T): NameOrId {

throw “unimplemented”;

}

let a = createLabel(“typescript”);

// let a: NameLabel

let b = createLabel(2.8);

// let b: IdLabel

let c = createLabel(Math.random() ? “hello” : 42);

// let c: NameLabel | IdLabel

条件类型约束

通常,条件类型中的检查会为我们提供一些新信息。就像使用类型保护缩小范围可以为我们提供更具体的类型一样,条件类型的真正分支将通过我们检查的类型进一步约束泛型。

看下面的例子:

type MessageOf = T[“message”];

//Type ‘“message”’ cannot be used to index type ‘T’.

上面这个例子ts 会检查错误,因为不知道T有没有message属性。我们应该约束T,TS将不再编译报错:

type MessageOf<T extends { message: unknown }> = T[“message”];

interface Email {

message: string;

}

type EmailMessageContents = MessageOf;

//type EmailMessageContents = string

如果我们想让MessageOf支持所有类型,如果没有message属性则默认返回never, 我们可以在约束的外面加上条件类型

type MessageOf = T extends { message: unknown } ? T[“message”] : never;

interface Email {

message: string;

}

interface Dog {

bark(): void;

}

type EmailMessageContents = MessageOf;

// type EmailMessageContents = string

type DogMessageContents = MessageOf;

// type DogMessageContents = never

在正确的分支里面,TS知道T拥有message属性

作为另一个示例,我们还可以编写一个名为flatte的类型,将数组类型展平为其元素类型,但在其他情况下不使用它们:

type Flatten = T extends any[] ? T[number] : T;

// Extracts out the element type.

type Str = Flatten<string[]>;

// type Str = string

// Leaves the type alone.

type Num = Flatten;

// type Num = number

Flatten是数组类型的时候,用了索引访问类型去获得string[]里元素的类型,其他类型时返回类型本身。

条件类型使用infer

我们只是发现自己使用条件类型来应用约束,然后提取类型。这是一个非常常见的操作,条件类型使它变得更容易。

条件类型为我们提供了一种使用infer关键字从我们在true分支中比较的类型中进行推断的方法。例如,我们可以在Flatte中推断元素类型,而不是使用索引访问类型“手动”将其取出:

type Flatten = Type extends Array ? Item : Type;

在这里,我们使用infer关键字声明性地引入一个名为Item的新泛型类型变量,而不是指定如何在true分支中检索T的元素类型。这使我们不必考虑如何挖掘和探索我们感兴趣的类型的结构。

我们可以使用推断关键字编写一些有用的助手类型别名。例如,对于简单的情况,我们可以从函数类型中提取返回类型:

type GetReturnType = Type extends (…args: never[]) => infer Return

? Return
never;

type Num = GetReturnType<() => number>;

//type Num = number

type Str = GetReturnType<(x: string) => string>;

//type Str = string

type Bools = GetReturnType<(a: boolean, b: boolean) => boolean[]>;

//type Bools = boolean[]

当从具有多个调用签名的类型(例如重载函数的类型)进行推断时,将从最后一个签名(这可能是最允许的“一网打尽”情况)进行推断。无法基于参数类型列表执行重载解析。

declare function stringOrNum(x: string): number;

declare function stringOrNum(x: number): string;

declare function stringOrNum(x: string | number): string | number;

type T1 = ReturnType;

//type T1 = string | number

分布式的条件类型

当条件类型作用于泛型类型时,当给定一个联合类型时,它们将成为分布式的。例如,以以下内容为例:

type ToArray = Type extends any ? Type[] : never;

如果给ToArray传入一个联合类型,那么条件类型将会应用每一个联合类型的成员,然后联合。

type ToArray = Type extends any ? Type[] : never;

type StrArrOrNumArr = ToArray<string | number>;

//type StrArrOrNumArr = string[] | number[]

1、这里发生的是StrOrNumArray分布在:

最后

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。

因此收集整理了一份《2024年Web前端开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

[外链图片转存中…(img-3wyBgaK9-1715623919786)]

[外链图片转存中…(img-wNNu45fM-1715623919786)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点!不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!

如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

  • 12
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值