是否有办法将泛型类型T
指定为Object,即而不是像数字或字符串这样的原语?
。这个克隆函数应该只允许对象作为输入,因为它将解构o
,将原型设置回原始对象的原型并返回。
export function clone<T>(o: T): T {
return Object.setPrototypeOf({ ...o }, o.constructor.prototype);
}
显示错误:
类型'T'上不存在属性'constructor'
object
类型(注意小写的o
)是专门为匹配"非基本的"而引入的。类型;即object
本质上是string | number | bigint | boolean | symbol | undefined | null
的补码。
不要与Object
(大写的O
)混淆,后者指的是任何可以像对象一样索引到的东西,本质上是undefined | null
的补充。毕竟,像"foo"
这样的字符串有一个明显的toUpperCase()
方法;当您调用"foo".toUpperCase()
时,它将"foo"
包装在String
对象中。如果你想要排除像string
这样的原语,你需要object
而不是Object
。
无论如何,这意味着clone()
的呼叫签名应该是这样的:
export function clone<T extends object>(o: T): T {
return Object.setPrototypeOf({ ...o }, o.constructor.prototype);
}
通过将类型参数T
约束为object
,您将只允许o
使用非基本参数:
clone(new Date()); // okay
clone({ a: 1, b: 2 }); // okay
clone([1, 2, 3]); // okay
clone("oops"); // error
clone(123); // error
clone(false); // error
clone(Symbol("wha")); // error
clone(undefined); // error
clone(null); // error
Playground链接到代码