In this chapter we learn about union types and type aliases.
union type
As we mentioned in the article on basic types, after defining a variable as a string type, it cannot be assigned another type. What if we need this variable to be both a string and a value ? At this point we can use the union type to achieve the requirements.
联合类型
(Union Types) indicates that the value can be one of multiple types, and an error will be reported for other types. for example:
let field: string | number
field = 'first' // 成功
console.log(field.length) // 5
field = 1 // 成功
console.log(field.length) // error TS2339: Property 'length' does not exist on type 'number'
field = false // error TS2322: Type 'boolean' is not assignable to type 'string | number'
Union types use to |
separate each type, in the above example field
can be either type string
or number
type. When it string
is , you can use string
attributes or methods, such as attributes length
; when it number
is , because number
there is no length
attribute , it will compile and report an error.
The above example is to 类型推论
get the exact type of the variable, so that the properties or methods of the corresponding type can be used. When TypeScript
we are not sure which type a variable of a joint type is, we can only access 共有的
properties or methods in all types of this joint type. for example:
function getLength(something: string | number): number {
return something.length; // error TS2339: Property 'length' does not exist on type 'string | number'. Property 'length' does not exist on type 'number'
}
In the above example, because length
is not a property sharedstring
by and , an error will be reported. Accessingnumber
shared properties of and is fine, for example:string
number
function getLength(something: string | number): string {
return something.toString();
}
A union type can be not only a basic type, but also an interface or a class, for example:
interface Bird {
fly(): void;
layEggs(): void;
}
interface Fish {
swim(): void;
layEggs(): void;
}
function getSmallPet(): Fish | Bird {
let bird: Bird = {
fly() {
},
layEggs() {
}
}
return bird
}
let pet = getSmallPet();
pet.layEggs(); // 成功
pet.swim(); // error TS2339: Property 'swim' does not exist on type 'Bird | Fish'.Property 'swim' does not exist on type 'Bird'
pet.fly(); // error TS2339: Property 'fly' does not exist on type 'Bird | Fish'.Property 'fly' does not exist on type 'Fish'
In the above example, the joint types are Fish
and Bird
, only their shared method layEggs
can be accessed, so swim
both and fly
will compile and report an error.
After reading the above introduction, you may think that can any
also achieve the same effect. In terms of code, it is indeed the case. Changing the joint type any
to will not compile and report an error, but at the same time you will lose TypeScript
the biggest function. . There are usage scenarios introduced Basic Types , for example, it can be used when the type is not clear at the compilation stage.any
type alias
类型别名
Used to give a type a new name. The method of aliasing is very simple, use the type keyword.
type alias = type(primitive type, union type, tuple...)
for example:
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
function getName(n: NameOrResolver): Name {
if (typeof n === 'string') {
return n;
} else {
return n();
}
}
Aliasing doesn't create a new type, it creates a new name to refer to that type. For example, in the above example, Name and string are actually the same type. Generally speaking, there is no special use for 原始类型
aliasing , and it is more used 联合类型
, for example:
type Field = string | number
let field: Field
field = 'first'
field = 1
Type aliases are sometimes similar to interfaces, but can be applied to 原始值
, 联合类型
, 元组
and 其它
any type you need to write by hand. Type aliases can be confusing when they are new to interfaces, for example:
type Field = {
num: number;
str: string;
}
interface inter {
num: number;
str: string;
}
In the above example, the use of type aliases and interfaces is relatively similar, but there are still obvious differences. I will discuss the specific differences in the next article on interfaces.
Type aliases can be used 泛型
, and the content 泛型
of will be introduced later. Here is a brief introduction to the use of type aliases. for example:
type Container<T> = {
value: T
}
let container: Container<string> = {
value: 'str'
}
value
The type at this time is determined according to the passed type parameter.
We can also use type aliases to refer to ourselves in properties:
type Container<T> = {
value: T;
children?: Container<T>
}
let container: Container<string> = {
value: 'str',
children: {
value: 'str2'
}
}