长久以来一直坚持用 TS 写各类 Web 应用,一个重要的乐趣就是 TS 的 Intellisence 在 VSCode 中自动提示做的特别好,甚至比其他真正的强类型语言例如 Java or Golang 都做的好。
而泛型 (Generic)是 Typescript 的一个很有用的语言特性,能够少写很多的模板代码,避免通过复制大段代码来复用功能或者逻辑。
方法很简单,就是检查一下传入的参数是不是存在,是就返回 true
,否则返回 false
。
在 React 中,Generic 遇到一个问题,就是 vscode 一直不停的提示语法错误。经过研究,发现原因就是 TS 编译器将泛型和 tsx
的组件标签没能正确的区分开来 (尖括号有歧义了)。有以下这么几个办法可以让泛型在 tsx
中和平共存。
泛型添加类型继承约束可以让编译器明确知道这是一个泛型声明。做法如下,
export const isPresentSomeObject = <T extends unknown>(t: T) => {
if (t && Object.keys(t as any).length > 0) {
return true
}
return false
}
让 T extens unkonwn
的原因是所有的类型都可以赋值给到 unknown
。另外, any
也可以起到同样的作用,但是用 any
就不再是类型安全的了。
另外一个小技巧就是在泛型中添加一个逗号,
export const isPresentSomeObject2 = <T,>(t: T) => {
if (t && Object.keys(t).length > 0) {
return true;
}
return false;
};
这个语法实际上原本是用来定义多个泛型参数的,但是即便是不再继续写第二个泛型参数,也不会报错。通过这个逗号的添加,让编译器明白了这里是一个泛型,而不是 React 组件。因为 React 的标签是不支持写逗号的。
最后一个办法就是不用箭头函数,回退到普通的函数声明中。
export function isPresentSomeObject3<T>(t: T): boolean {
if (t && Object.keys(t).length > 0) {
return true;
}
return false
}
看起来,这是最没有歧义的一个方法了,编译器对于这样的写法是非常的认可。也算一个不是技巧的技巧吧 (是不是所谓的大智若愚)。