今天想对react-transiton-group进行二次封装,发现了typescript中interface和type的区别之一,就是接口(interface)不能扩展(extends)联合类型。
报错
interface CTransitionProps extends CSSTransitionProps {
animation?: AnimationName,
wrapper?: boolean
}
TS2312: An interface can only extend an object type or intersection of object types with statically known members.
接口只能扩展对象类型或对象类型与静态已知成员的交集。
什么是联合类型?
我这里直接把typescript官方文档的例子拿过来用了
这个函数中形参padding的期待类型是`padding或者number。
function padLeft(value: string, padding: any) {
if (typeof padding === "number") {
return Array(padding + 1).join(" ") + value;
}
if (typeof padding === "string") {
return padding + value;
}
throw new Error(`Expected string or number, got '${padding}'.`);
}
但是把padding参数类型指定成了any,这就是说我们可以传入一个既不是 number也不是 string类型的参数。
let indentedString = padLeft("Hello world", true); // 编译阶段通过,运行时报错
在传统的面向对象语言里,我们可能会将这两种类型抽象成有层级的类型。 这么做显然是非常清晰的,但同时也存在了过度设计。 padLeft原始版本的好处之一是允许我们传入原始类型。 这样做的话使用起来既简单又方便。 如果我们就是想使用已经存在的函数的话,这种新的方式就不适用了。
我们可以用联合类型代替any
function padLeft(value: string, padding: string | number) {
// ...
}
联合类型表示一个值可以是几种类型之一。 我们用竖线( |)分隔每个类型,所以 number | string表示一个值可以是 number 或者 string。
CSSTransitionProps
CSSTransitionProps就是一个联合类型
使用type
type CTransitionProps = CSSTransitionProps & {
animation?: AnimationName,
wrapper?: boolean
}