当前位置:网站首页>Typescript learning [7] advanced types: Union type and cross type
Typescript learning [7] advanced types: Union type and cross type
2022-06-09 04:46:00 【Large American without sugar】
Joint type
Joint type (Unions) To represent a variable 、 The type of the parameter is not a single atomic type , It may be a combination of many different types .
We mainly pass | Operators separate the syntax of types to represent joint types . here , We can | Analogy for JavaScript Logical or in ||, But the former means possible types .
for instance , We encapsulate a program that will string perhaps number The input value of type is converted to ' Numbers + “px” Function of format , As shown in the following code :
function formatPX(size: unknown) {
if (typeof size === 'number') {
return `${
size}px`;
}
if (typeof size === 'string') {
return `${
parseInt(size) || 0}px`;
}
throw Error(' Only conversion is supported number And string');
}
console.log(formatPX(13)); // 13px
console.log(formatPX('13px')); // 13px
explain : Before learning about union types , We may have to use any or unknown Type to represent the type of the parameter ( In order to form good habits , Recommended unknown).
The problem with this approach is , Calling formatPX when , We can pass arbitrary values , And it can be detected by static type ( Use any And so it is ), But the runtime will still throw an error , for example :
formatPX(true);
formatPX(null);
This is obviously not in line with our expectations , because size It should be more specific , It can or can only be number or string The types of these two optional types .
Fortunately, there are joint types , We can use a more explicit expression May be number or string The type of Union To annotate size Parameters , As shown in the following code :
function formatPX(size: number | string) {
// ...
}
Of course , We can combine any 、 Any type can be used to construct a type that more meets our demands . such as , We want to add another one to the previous example unit Parameters indicate possible units , At this time, you can declare a union type composed of string literal types , As shown in the following code :
function formatPX(size: number | string, unit: 'px' | 'em' | 'rem' | '%' = 'px') {
if (typeof size === 'number') {
return `${
size}${
unit}`;
}
if (typeof size === 'string') {
return `${
parseInt(size) || 0}${
unit}`;
}
throw Error(' Only conversion is supported number And string');
}
console.log(formatPX(21, 'rem')); // 21rem
console.log(formatPX(77, '%')); // 77%
The above code defines formatPX The second parameter of the function unit, Its type is made up of ‘px’、‘em’、‘rem’、‘%’ A collection of types consisting of string literal types .
We can also use type aliases to extract the above union types , And then combine them further , As shown in the following code :
type ModernUnit = 'vh' | 'vw';
type SimpleUnit = 'px' | 'em' | 'rem';
type UnitConcat = ModernUnit | SimpleUnit;
We can also combine interface types to represent more complex structures , An example is shown below :
interface Bird {
fly(): void;
layEggs(): void;
}
interface Fish {
swim(): void;
layEggs(): void;
}
const getPet: () => Bird | Fish = () => {
return {
// ...
} as Bird | Fish
};
const Pet = getPet();
Pet.layEggs();
Pet.fly(); // ts(2339) 'Fish' No, 'fly' attribute ; 'Bird | Fish' No, 'fly' attribute
As you can see from the example above , In union type , We can directly access the properties owned by each interface member 、 Method , And will not prompt the wrong type . however , If it is a unique attribute of an individual member 、 Method , We need to treat them differently , At this time, type guard is introduced to distinguish different member types .
It's just , under these circumstances , We also need to use the in Type guard for operator judgment , As shown in the following code :
if (typeof Pet.fly === 'function') {
// ts(2339)
Pet.fly(); // ts(2339)
}
if ('fly' in Pet) {
Pet.fly();
}
because Pet The type of can be either Bird It could be Fish, This means that in the 1 Line may pass Fish Type acquisition fly attribute , but Fish There is no type fly Attribute definitions , So there will be a prompt ts(2339) error .
Cross type
stay TypeScript in , There is also a type of logic and behavior —— Cross type (Intersection Type), It can combine multiple types into one type , The merged type will have the properties of all member types .
have access to & Operator to declare the cross type , As shown in the following code :
type Test = string & number;
Obviously , If we just put the original type 、 Literal type 、 Atomic types such as function types are combined into cross types , It's useless , Because no type can satisfy that it belongs to multiple atomic types at the same time , For example, since string The type is number type . therefore , In the above code , Type the alias Test The type of is never.
Merge interface types
The real use of joint types is to combine multiple interface types into one type , So as to achieve the effect of equivalent interface inheritance , That is, the so-called merge interface type , As shown in the following code :
type IntersectionType = {
id: number; name: string; } & {
age: number };
const mixed: IntersectionType = {
id: 1,
name: 'Jae',
age: 23
}
In the example above , We pass the cross type , bring IntersectionType At the same time, I have id、name、age All attributes , Here, we can try to understand merging interface types as Union .
What effect will it have if there are attributes with the same name in the merged multiple interface types ?
If the type of the property with the same name is incompatible , For example, two interface types with the same name in the above example name One of the attribute types is number, The other is string, After the merger ,name The type of attribute is number and string The intersection of two atomic types , namely never, As shown in the following code :
type IntersectionType = {
id: number; name: string; } & {
age: number; name: number };
const mixed: IntersectionType = {
id: 1,
name: 'Jae', // ts(2322) error ,'number' Type cannot be assigned to 'never' type
age: 23
}
here , We give mixed Any type of name Property values will prompt the wrong type . And if we don't set name attribute , It will prompt a missing required name Property error . under these circumstances , It means that the above code intersects IntersectionType Type is a useless type .
If the type of the property with the same name is compatible , For example, one is number, The other is number Subtypes of 、 Number literal type , After the merger name The type of an attribute is a subtype of both .
In the example shown below name The type of the property is the numeric literal type 2, therefore , We can't put any non 2 Values other than give name attribute .
type IntersectionType = {
id: number; name: 2; } & {
age: number; name: number };
const mixed: IntersectionType = {
id: 1,
name: 22, // ts(2322) You can't type “22” Assign to type “2”
age: 23
}
Merge union type
in addition , We can merge union types into a cross type , This cross type needs to satisfy different union type restrictions at the same time , That is, the same type members of all union types are extracted . here , We can also understand merging union types as finding intersections .
In the following example , The type where two union types intersect IntersectionUnion In fact, it's equivalent to ‘em’ | ‘rem’, So we can only ‘em’ perhaps ‘rem’ The string is assigned to IntersectionUnion Variable of type .
type UnionA = 'px' | 'em' | 'rem' | '%'
type UnionB = 'vh' | 'em' | 'rem' | 'pt'
type IntersectionUnion = UnionA & UnionB
const test1: IntersectionUnion = 'em'
const test2: IntersectionUnion = 'px' // ts(2322) You can't type “"px"” Assign to type “"em" | "rem"”
const test3: IntersectionUnion = 'pt' // ts(2322) You can't type “"pt"” Assign to type “"em" | "rem"”
Since it is seeking intersection , If multiple union types do not have the same type member , The type crossed out naturally is never 了 , As shown in the following code :
type UnionC = 'em' | 'rem';
type UnionD = 'px' | 'pt';
type IntersectionUnion2 = UnionC & UnionD;
const Test: IntersectionUnion2 = 'any' as any; // ts(2322) Cannot assign 'never' type
In the example above , because UnionC and UnionD There is no intersection , Cross out the type IntersectionUnion2 Namely never, So we can't assign any type of value to IntersectionUnion2 Variable of type .
union 、 Cross combination
In the previous example , We combine some 、 Cross types are abstracted into type aliases , And then combine it as an atomic type 、 cross . Actually , union 、 The cross type itself can be combined directly , This involves |、& The priority of operators . actually , union 、 The crossover operator is not only consistent in behavior , The priority and JavaScript The logic of or ||、 Logic and && Operators are consistent .
Union operator | The priority of the lower than Crossover operator &, Again , We can use small parentheses () To adjust the priority of operators .
type ITest1 = {
id: number; } & {
name: string; } | {
id: string; } & {
name: number; }; // The crossover operator takes precedence over the union operator
type ITest2 = ('px' | 'em' | 'rem' | '%') | ('vh' | 'em' | 'rem' | 'pt'); // Adjust priorities
Type reduction
If you will string Original type and “string Literal type ” What is the effect of combining into a union type ? The effect is to reduce the type to string 了 , As shown below :
type TStr = 'string' | string; // The type is string
type TNum = 2 | number; // The type is number
type TBoolean = true | boolean; // The type is boolean
TypeScript This scenario has been reduced , It puts literal types 、 Enumeration member types are reduced , Keep only the original type 、 Enumeration type and other parent types , It's reasonable “ Optimize ”.
But this reduction , But greatly weakened IDE The ability to automatically prompt , As shown in the following code :
type BorderColor = 'black' | 'red' | 'green' | 'yellow' | 'blue' | string; // The type is reduced to string
In the above code , We hope IDE It can automatically prompt the string literal of the annotation , But because the type is reduced to string, All string literals black、red I can't automatically prompt you .
TypeScript The authorities actually offer a way , It allows type reduction to be controlled . As shown in the following code , We just need to add... To the parent type & {} that will do .
type BorderColor = 'black' | 'red' | 'green' | 'yellow' | 'blue' | string & {
}; // Literal types are reserved
The effect is shown below :

Besides , When a member of a union type is an interface type , If the attribute of one interface is a subset of the attribute of the other interface , This attribute also reduces the type , As shown in the following code :
type UnionInterce =
| {
age: '1';
}
| ({
age: '1' | '2';
[key: string]: string;
});
Here because ‘1’ yes ‘1’ | ‘2’ Subset , therefore age The attribute of becomes ‘1’ | ‘2’.
Take advantage of this feature , To solve a problem : How to define the following age Attributes are numeric types , Other uncertain properties are objects of string type data structures ?
{
num: 1, // Numeric type
str: 'str', // Other indeterminate properties are string types
...
}
We must use the joint type and type reduction of the two interfaces , The core of this problem is to find a solution that is both number Subtypes of , such age After the type reduction, the type is number; It's also string Subtypes of , In this way, the properties and string Constraint relation of index type .
Which type satisfies this condition ? It is never
never One feature is that it is a subtype of all types , Naturally also number and string Subtypes of , So the answer is as follows :
type UnionInterce =
| {
age: number;
}
| ({
age: never;
[key: string]: string;
});
const test: UnionInterce = {
age: 2,
string: 'string'
}
In the above code , First, it defines number Type of age attribute , And then defined never Type of age attribute , Equivalent to age The type of the attribute is determined by number and never The union of types , So we can take number Type value ( For example, numerical literal quantity 1) give age attribute ; But you can't put any other type of value ( For example, string literal ‘string’ ) give age.
meanwhile , Interface types defined later , There is also an additional definition of string Type string index signature . because never At the same time string Subtypes of types , therefore age The type of the property does not conflict with the type of the string index signature . As shown in the code , We can put one age The attribute is 2、string The attribute is ‘string’ The object literal of is assigned to UnionInterce Variable of type test.
边栏推荐
- Format interchange among Yolo, coco and VOC datasets
- 数据库的三大范式
- Openstack Learning Series 1: openstack introduction, installation and deployment of basic environment
- Template: constant coefficient homogeneous linear recurrence (linear algebra, polynomial)
- OpenGL 01 - créer une fenêtre
- (4) Data responsive
- MySQL scheduled backup restore
- 渗透测试路径字典、爆破字典
- National information security competition for college students (ciscn) -reverse- recurrence (part)
- openGL_01-创建窗口
猜你喜欢

MySQL queries which table in the database has the most fields

2022年安全员-A证考试试题及在线模拟考试
![[006] [ESP32开发笔记] 使用Flash下载工具烧录固件步骤](/img/a0/5d5e6c076d267c0ffe4c1e8f10e408.png)
[006] [ESP32开发笔记] 使用Flash下载工具烧录固件步骤

1030. 距离顺序排列矩阵单元格●

openGL_ 02 point line surface triangle

Give an example to illustrate the cell and num of lstmcell in TF_ What does unit mean

Faster RCNN

故障排查:阿里云轻量应用服务器中的MySQL容器自行停止

Internet behavior networking

蘑菇街半年营收1.68亿:同比降29% 运营亏损2.4亿
随机推荐
(7)属性绑定
View local public IP
PHP e-signature SaaS API docking process
2022年高压电工考试模拟100题及答案
2022年高处安装、维护、拆除特种作业证考试题库及模拟考试
(3) Data binding instructions
Mmdet detection box font color modification
Page components of wechat applet development
(9) Branch loop structure
2022 safety officer-a certificate examination questions and online simulation examination
Keepalived configure virtual IP
(8) Style binding
Gradle channel package configuration
[6.824 distributed system] LEC 6 & 7: fault tolerance: raft
Rendering pipeline ---- easy to understand and introduce to the interviewer
MySQL scheduled backup restore
Mysql database locking mechanism
数据库的三大范式
openGL_ 02 point line surface triangle
迪文2K高分辨率智能屏发布4款新品