有没有办法指定泛型函数的基类型?

Is there a way to specifiy the base type of a generic function?

有没有办法将泛型类型 T 指定为对象,即 而不是 像数字或字符串这样的原始类型?

例如这个克隆函数应该只允许对象作为输入,因为它会解构 o,将原型设置回原始对象的原型,然后 return 那个。

export function clone<T>(o: T): T {
  return Object.setPrototypeOf({ ...o }, o.constructor.prototype);
}

linter 显示错误:

Property 'constructor' does not exist on type 'T'

The object type(注意小写 o)是专门为匹配“非原始”类型而引入的;也就是说,object 本质上是 string | number | bigint | boolean | symbol | undefined | null.

的补充

Don't confuse it with 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);
}

通过 constraining 类型参数 Tobject,您将只允许 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 link to code