I want to get along with the "?" And "!" That I often see in TypeScript
Hi, I'm oreo, a front-end engineer from iCARE Co., Ltd.
Our front end is developed with Vue.js, TypeScript. In a certain PR, we received the following review from our technical advisor .
I was worried when refactoring, but I saw some unnecessary parts with? Cast! |? | As are all dangerous codes and the burden on the reviewer is heavy, so only the parts that are necessary properly Please be careful to put it in
I've been using it easily so far ?
, !
so I'd like to sort out their behavior!
?
about
Optional parameter ( ?
)
Overview
If you add an optional parameter to the argument , that argument can be omitted . In Example 1.1, if test()
you execute, you Expected 1 arguments, but got 0.
will get angry , but if you add an optional parameter (Example 1.2), you will not get angry.
//例1.1
const test = (x:number,y:number):void=>{
console.log(x);
};
test(1); //エラー Expected 2 arguments, but got 1.
//例1.2
const test = (x:number,y?:number):void=>{
console.log(x);
}
test(1); //OK
important point
- In Example 1.2, when the optional parameter is used, the argument x is
string | undefined
recognized as a union type of . - Also, optional parameters must always be written at the end of the argument (Example 1.3).
//例1.3
const test = (x?:number,y:number):void=>{
console.log(x,y);
};
//エラー A required parameter cannot follow an optional parameter.
Supplement: Default parameters
You can also give default values to optional parameters by writing something like ?. Also, the default parameter does not have to be written at the end of the argument.
//例1.4
const test = (x: number, y = 3): void => {
console.log(x+y);
console.log(x);
};
test(1); //OK
// console.log(x+y)は4と出力
// console.log(x)は1と出力
Optional chaining ( ?.
)
Overview
Available in TypeScript 3.7 and above. null
And undefien
with respect to the property .
Referring the error occurs (for example, 2.1) is, ?.
and use, the error does not occur, undefiend
it is returned (for example, 2.2) .
//例2.1
type Address = {
prefecture: {
name: string
city?: {
name: string
}
}
}
const address: Address = {
prefecture: {
name: 'tokyo',
},
}
const targetAddress = address.prefecture.city.name //エラー Object is possibly 'undefined'.
console.log(targetAddress)
//例2.2
type Address = {
prefecture: {
name: string
city?: {
name: string
}
}
}
const address: Address = {
prefecture: {
name: 'tokyo',
},
}
const targetAddress = address.prefecture.city?.name //OK
console.log(targetAddress)
important point
?.
If you use, it will be evaluated short-circuited . Under short-circuit evaluation,?.
the left side than thenull
killingundefiend
case of,?.
you more right-hand side is no longer evaluated (executed).
Null coalescing operator ( ??
)
Overview
Available in TypeScript 3.7 and above. Returns the right value if the left side is null
or undefiend
, otherwise returns the left value (Example 3.1).
//例3.1
const name = null ?? 'Yamada Taro';
console.log(name);
// 'Yamada Taro'が出力
important point
??
Returns the value on the left, ||
unlike the OR operator , null
or undefiend
for falsy values other than (for example, ''
or 0
) .
//例3.2 OR演算子
const age = 0 || 18;
console.log(age);
// 18が出力
//例3.3 Null合体演算子
const age = 0 ?? 18;
console.log(age);
// 0が出力
Null coalescing operator ( ??=
)
Overview
Available in TypeScript 4.0 and above. Substitute if the left side is null
orundefiend
(Example 4.1).
//例4.1
const pilot = { name: null };
pilot.name ??= "shinji";
console.log(pilot.name); //shinjiが出力
//例4.2
const pilot = { name: "shinji" };
pilot.name ??= "asuka";
console.log(pilot.name); //shinjiが出力。asukaが代入されない。
The two lines in Example 4.3 give the same result.
const pilot = { name: null };
//例4.3
pilot.name ??= "shinji"; //Null合体代入演算子
pilot.name = pilot.name ?? "shinji"; //Null合体演算子
important point
The left-hand side is null
, or undefiend
the case of falsy a value other than (for example, ''
Ya 0
), not assigned .
//例4.4
const pilot = { age: 0 };
pilot.age ??= 14;
console.log(pilot.age) //0が出力
!
about
Non-null assertion operator ( !
)
Overview
For nullable types ( T | null
or T | null | undefiend
), !
you can use non-null assertions ( ) to make it clear to the compiler that the type null | undefiend
is notT
.
//例5.1
type Dog = { name: string };
const mydog = { name: "sora" };
const getDog = (dog?: Dog) => {
console.log(dog.name); //エラー Object is possibly 'undefiend'
};
getDog(mydog);
//例5.2
type Dog = { name: string };
const mydog = { name: "sora" };
const getDog = (dog?: Dog) => {
console.log(dog!.name); //OK
};
getDog(mydog);
important point
It null | undefiend
may be better not to use it too much, because it may make it clear that it is not compulsory and you may not notice the change in type.
Clear Assignment Assertion ( !
)
Overview
If a variable may not have been assigned a value (if TypeScript cannot be statically detected), as in Example 6.1, you will be offended by using that variable. However, !
you can use to make it clear to the compiler that a variable has been assigned a value by the time you use it.
//例6.1
let name: string;
const addName = (val: string) => {
name = val;
};
addName("shinji");
console.log(name); //エラー Variable 'name' is used before being assigned.
//例6.2
let name!: string;
const addName = (val: string) => {
name = val;
};
addName("shinji");
console.log(name); //OK
important point
If the variable is not assigned due to a code change etc., you will not notice it, so basically it may be better not to use it too much.
Finally
By summarizing it again, my mind was organized. ?
, !
Is very convenient, but you should use it after fully understanding its danger (notice the change of type etc.). In addition, among the team members, ?
, !
I thought also the kana break-and coding rules for clarification is also an important level of understanding about.
reference
O'Reilly Japan, Inc. "Programming TypeScript"
Author: oreo2990