在 TypeScript 中,enum
算是还蛮常会使用到的型别,但有时如果用的不好或观念不够清楚的话,就会有点痛苦而不知所以然。
以下面这个 GENDER
来说:
enum GENDER {
MALE = 'male',
FEMALE = 'female',
}
我们知道使用 GENDER.MALE
可以取得 "male"
,所以有时侯会直觉的想说,那 "male"
应该算是 GENDER
的子集合吧!?而这也是笔者在使用 enum 时很容易忽略或犯的错误。
让我们来做一点小测验,读者可以想想看,下面这些条件会是 true 或 false:
type T1 = GENDER extends string ? true : false;
type T2 = string extends GENDER ? true : false;
type T3 = number extends GENDER ? true : false;
type T4 = 'male' extends GENDER ? true : false;
type T5 = GENDER.MALE extends GENDER ? true : false;
type T6 = GENDER.MALE extends string ? true : false;
这里的重点是要区分清楚 "male"
、"female"
、GENDER
(enum) 和 string
它们彼此间的关系,如果我们用一张图来表示,会类似像这样:
特别留意上图中的 GENDER.MALE
和 "male"
的部分。
发现了吗?虽然说我们知道,透过 GENDER.MALE
可以取得 "male"
,但实际上 "male"
并不是 GENDER
这个 enum 的子集合!更具体来说,从值的角度思考时 GENDER.MALE
和 "male"
是一样的,但从型别的角度思考是 GENDER.MALE
和 "male"
互不是彼此的子集合,这个概念真的蛮重要的。上面提供的程序码,便是用 Conditional Type 的方式来验证这样的关系:
enum STRING_GENDER {
MALE = 'male',
FEMALE = 'female',
}
type T1 = STRING_GENDER extends string ? true : false; // true
type T2 = string extends STRING_GENDER ? true : false; // false
type T3 = string extends STRING_GENDER.MALE ? true : false; // false
type T4 = 'male' extends STRING_GENDER ? true : false; // false
type T5 = 'male' extends STRING_GENDER.MALE ? true : false; // false
type T6 = STRING_GENDER.MALE extends STRING_GENDER ? true : false; // true
type T7 = STRING_GENDER.MALE extends string ? true : false; // true
type T8 = STRING_GENDER extends STRING_GENDER.MALE ? true : false; // false
另外,虽然 GENDER.MALE
和 "male"
彼此之间没有从属关系外,但它们都还是属於型别 string 的子集合。
上面这个部分要谢谢同事 Peter 协助笔者厘清与理解。
上面说明的是 string enums 的情况,也就是 enum 的 value 是 string 时,但另外常用的 enum 还有 numeric enums 这时候在集合的表现上会有所不同,有兴趣的读者可以再自行尝试看:
enum NUMERIC_GENDER {
MALE,
FEMALE,
}
type T11 = NUMERIC_GENDER extends number ? true : false; // true
type T12 = number extends NUMERIC_GENDER ? true : false; // true
type T13 = number extends NUMERIC_GENDER.MALE ? true : false; // true
type T14 = 10 extends NUMERIC_GENDER ? true : false; // true
type T15 = 10 extends NUMERIC_GENDER.MALE ? true : false; // true
type T16 = NUMERIC_GENDER.MALE extends NUMERIC_GENDER ? true : false; // true
type T17 = NUMERIC_GENDER.MALE extends number ? true : false; // true
type T18 = NUMERIC_GENDER extends NUMERIC_GENDER.MALE ? true : false; // false
type T19 = NUMERIC_GENDER.MALE extends NUMERIC_GENDER.FEMALE ? true : false; // false
https://tsplay.dev/w11MGw @ TypeScript Playground
安装Flask跟套件 pip install flask pip install flask-res...
上面讲到job会由系统分配,但为什麽我们又能把job当作参数传入coroutine呢? 继承 在前面...
(转眼间到最後两天,发现想谈及的主题谈不完,所以最後这两篇整合宝石的文章会特别长~,因为如果照之前...
Google reCAPTCHA是Google开发的防堵机器人验证API, 原本是设计给网页使用, ...
前言 接下来这一篇算是收割前面几个章节的章节小练习,基本上我是尽量规划每过几个章节就有一些小作业、小...