Typescript 那些好用的技巧
1、 类型断言
类型断言可以明确的告诉 TypeScript 值的详细类型,
在某些场景, 我们非常确认它的类型, 即使与 typescript 推断出来的类型不一致. 那我们可以使用类型断言.
语法如下:
< 类型 > 值
值 as 类型
// 推荐使用这种语法. 因为容易跟泛型, react 中的语法起冲突
举个例子, 如下代码, padding 值可以是 string , 也可以是 number, 虽然在代码里面写了 Array(), 我们明确的知道, padding 会被parseint 转换成 number 类型, 但类型定义依然会报错.
function padLeft ( value : string , padding : string | number ) {
// 报错: Operator ‘+’ cannot be applied to
// types ‘string | number’ and ‘number’
return Array ( padding + 1 ). join ( ” “ ) + value ;
}
解决方法, 使用类型断言. 告诉 typescript 这里我确认它是 number 类型, 忽略报错.
function padLeft ( value : string , padding : string | number ) {
// 正常
return Array ( padding as number + 1 ). join ( ” “ ) + value ;
}
但是如果有下面这种情况, 我们要写很多个 as 么?
function padLeft ( value : string , padding : string | number ) {
console . log (( padding as number ) + 3 );
console . log (( padding as number ) + 2 );
console . log (( padding as number ) + 5 );
return Array (( padding as number ) + 1 ). join ( ‘ ‘ ) + value ;
}
2、 类型守卫
类型守卫有以下几种方式, 简单的概括以下
-
typeof: 用于判断 “number”,”string”,”boolean”或 “symbol” 四种类型.
-
instanceof : 用于判断一个实例是否属于某个类
-
in: 用于判断一个属性/方法是否属于某个对象
-
字面量类型保护
上面的例子中, 是 string | number 类型, 因此使用 typeof 来进行类型守卫. 例子如下:
function padLeft ( value : string , padding : string | number ) {
if ( typeof padding === ‘number’ ) {
console . log ( padding + 3 ); //正常
console . log ( padding + 2 ); //正常
console . log ( padding + 5 ); //正常
//正常
return Array ( padding + 1 ). join ( ‘ ‘ ) value ;
}
if ( typeof padding === ‘string’ ) {
return padding + value ;
}
}
相比较 类型断言 as , 省去了大量代码. 除了 typeof , 我们还有几种方式, 下面一一举例子.
-
instanceof :用于判断一个实例是否属于某个类
class Man {
handsome = ‘handsome’ ;
}
class Woman {
beautiful = ‘beautiful’ ;
}
function Human ( arg : Man | Woman ) {
if ( arg instanceof Man ) {
console . log ( arg . handsome );
console . log ( arg . beautiful ); // error
} else {
// 这一块中一定是 Woman
console . log ( arg . beautiful );
}
}
-
in : 用于判断一个属性/方法是否属于某个对象
interface B {
b : string ;
}
interface A {
a : string ;
}
function foo ( x : A | B ) {
if ( ‘a’ in x ) {
return x . a ;
}
return x . b ;
}
-
字面量类型保护
有些场景, 使用 in, instanceof, typeof 太过麻烦. 这时候可以自己构造一个字面量类型.
type Man = {
handsome : ‘handsome’ ;
type : ‘man’ ;
};
type Woman = {
beautiful : ‘beautiful’ ;
type : ‘woman’ ;
};
function Human ( arg : Man | Woman ) {
if ( arg . type === ‘man’ ) {
console . log ( arg . handsome );
console . log ( arg . beautiful ); // error
} else {
// 这一块中一定是 Woman
console . log ( arg . beautiful );
}
}
3、双重断言
有些时候使用 as 也会报错,因为 as 断言的时候也不是毫无条件的. 它只有当S类型是T类型的子集,或者T类型是S类型的子集时,S能被成功断言成T.
所以面对这种情况, 只想暴力解决问题的情况, 可以使用双重断言.
function handler ( event : Event ) {
const element = event as HTMLElement ;
// Error: ‘Event’ 和 ‘HTMLElement’
中的任何一个都不能赋值给另外一个
}
如果你仍然想使用那个类型,你可以使用双重断言。首先断言成兼容所有类型的any
function handler ( event : Event ) {
const element = ( event as any ) as HTMLElement ;
// 正常
}
三. 巧用 typescript 支持的 js 最新特性优化代码