这是我们今天要聊的内容(不是业配),老样的,如果你已经可以轻松看懂,欢迎直接左转去看我同事 Ken 精彩的文章 — 「From State Machine to XState」。
多数 JavaScript 的开发者都知道,在 JS 中有 typeof operator 可以使用,使用上虽然有一些要留意的细节,但基本上 typeof
可以帮开发者判断某个变数的型别:
// https://javascript.info/types#type-typeof
typeof undefined; // "undefined"
typeof 0; // "number"
typeof true; // "boolean"
typeof 'foo'; // "string"
typeof (() => {}); // "function"
typeof null; // "object"
但今天我们要聊的是 TS 中的 Typeof Type Operator,多一个 type 差很多。
这个 typeof
的用法其实非常简单,我们知道在 TypeScript 中,即使没有针对变数定义型别(Type Annotation),它还是会自动帮我们推导出该变数对应的型别,只要把滑鼠移到该变数上方,就可以看到 TS 自动帮变数推导出其可能的型别:
这里 TypeScript 会自动把 conference 这个「变数」推导为如下的「型别」:
const conference: {
name: string;
year: number;
isAddToCalendar: boolean;
website: string;
};
但这个被自动推导出来的型别需要滑鼠移上去时才看得到,有没有什麽方式能够把这个「自动推导的结果」建立成一个可以被使用的型别呢?
有,就是 Typeof Type Operator,它的语法一样就是 typeof
,後面可以接「变数」或「属性」:
type Conference = typeof conference;
这个建立出来的型别 Conference
就会是刚刚一开始滑鼠移到变数 conference
上时显示的结果:
那回到今天最开始的例子:
const conference = {
name: 'MOPCON',
year: 2021,
isAddToCalendar: true,
website: 'https://mopcon.org/2021/',
};
type ConferenceKeys = keyof typeof conference;
搭配在第 4 天时对 keyof
的了解,读者应该可以想到 ConferenceKeys
的结果会是什麽。因为 typeof conference
是物件型别,所以 keyof typeof conference
就会是把所有该物件型别所有的 key 取出组成 Union Type:
读者也许会好奇,不能直接用 keyof conference
就好,一定要在 conference
前面加上 typeof
吗?学习 TS 的重点之一就是拿掉看看会发生什麽事,现在就让我们拿掉原本的 typeof
看看:
这时候 TypeScript 报错了,错误内容是:
'conference' refers to a value, but is being used as a type here. Did you mean 'typeof conference'?
意思是,conference
是 value,但它却被当成 type 来使用。为什麽会有这个错误呢?
还记得 conference
本身是一个 JavaScript 中的变数而不是 TypeScript 中的型别吗?因为 keyof
後面只能接的是「型别(Type)」,不能接 JavaScript 的「值(value)」,因此,一定会需要透过 typeof
先把 JS 的变数值转成 TS 的型别後,才能使用 keyof
这个 operator。
其实...也没什麽好区分的。
虽然这两个的语法都是 typeof
,但执行的时间点是完全不同的,JavaScript 的 typeof operator 会在程序执行时(runtime)呼叫,而 TypeScript 的 typeof type operator 则只有在 TypeScript 中「操作型别」时会用到,一旦把 .ts
编译成 .js
後,到了 runtime 会无影无踪(毕竟 JS 原生并没有这种强型别的概念)。
可以分辨的出那个是 JavaScript 的 Typeof Operator,那个是 TypeScript 的 Typeof Type Operator 吗?
const conference = {
name: 'MOPCON',
year: 2021,
isAddToCalendar: true,
website: 'https://mopcon.org/2021/',
};
type Conference = typeof conference;
const typeofConference = typeof conference;
还记得在 Day11 中曾提到,透过 Template Literal Types 可以把 enum 的 values 取出变成联集吗?
enum MANUFACTURE {
APPLE = 'apple',
SAMSUNG = 'samsung',
GOOGLE = 'google',
SONY = 'sony',
}
type Manufacture = `${MANUFACTURE}`; // "apple" | "samsung" | "google" | "sony"
现在如果是想要把 enum 的 key 取出变成 union types 的话,则可以使用到今天提的 Typeof Type Operator:
// Get all keys of enum
type ManufactureKeys = keyof typeof MANUFACTURE; // "APPLE" | "SAMSUNG" | "GOOGLE" | "SONY"
是不是很酷又很方便啊!现在读者就可以根据需要取得 enum 的 keys union 或 values union 了。
https://tsplay.dev/mAV3RW @ TypeScript Playground
笔者今年将会在 MOPCON 2021 分享主题「用 Type 建立 Type:一起来当个 TypeScript 的型别魔术师」,提供给对 TypeScript 有兴趣,又觉得每天追文章实在太辛苦的你来参考看看!但即使报名了 MOPCON 还是可以继续追踪铁人赛啦!
<<: DAY28 - [React] useContext 概念篇
>>: 连续 30 天 玩玩看 ProtoPie - Day 13
Colab连结 今天要探讨的主题在模型从CNN Layer 转变成 Dense Layer 时,使用...
前言 看了一些交易资料,现在来看看一些帐务相关的资料吧。 参考网站:Position 本日程序码使用...
清理方法(The sanitization method),清除(purge),将使数据恢复不可行,...
保持同步 资料工程师修炼之路走到现在,真的没有一个系统能同足满足资料储存、查询和逻辑处理,现实世界的...
前几篇介绍了 Form 的基本操作与概念,也介绍了如何在表单中加入验证,最後要来介绍 Angular...