刚开始学Angular的时候,面对Typescript从来没有慌过,因为在我眼里,一切皆any……
但是好奇心是一个程序猿最起码的底线,这个不能没有。
想想以前学习JAVA的时候,被各种类型、继承、多态、泛型、反射等概念包围,都没怂过。
但是把一个弱类型语言硬钢成强类型语言,还是有些内容需要补充知道的。
说起Unit Types,刚开始我以为其实就是枚举类型,但是枚举类型也会有个变量名称,Unit Type没有。
按照官方的说法,Unit Types是基本类型的子集(子类型)。我想,都基本类型了,还有什么鬼子集。看了官方文档后,才渐渐有所了解。
我们在设计一个函数的时候,使用了Unit Types进行类型声明一个参数direction
declare function pad(s: string, n: number, direction: "left" | "right"): string;
pad("hi", 10, "left"); //这么做没问题,但是如果direction是参数,你就要小心了
用惯其他强类型语言过来人,看到这个函数的时候,很自然而然的理解为,不就两个特定值的字符串吗?我在使用该函数的时候,直接传入字符串类型的变量就行了吧?
let s = "right";
pad("hi", 10, s); // error: 'string' is not assignable to '"left" | "right"'
结果报错了,很多时候,我在用第三方TS类库的时候,感到莫名其妙。你要的值,我给你了,你还矫情。
Argument of type 'string' is not assignable to parameter of type '"left" | "right"'.
其实,人家是这个意思:
let s: "left" | "right" = "right";
pad("hi", 10, s);
也就是说,你把变量传进去之前,先要按照函数参数里限定类型的方式来声明变量。官网是这么说的:
"left" | "right";
是一种单位类型,表面上看上去是字符串,实际上,它只是把字符串类型的两个特定值组成一种新的类型,如果直接使用s="right"
,类型是string,可人家要的不是String,而是那两个特殊值。对于TS编译器来说,你把入参的类型从一个限定小夫妻扩展到同类大家庭去了,风险也就扩大了,不够严谨。即使大家都是屌丝,气质这快必须拿捏的死死地。
所以在使用某些第三方类库的时候,老老实实的给你的变量声明特定类型吧。