首页 > 解决方案 > 部分擦除 TypeScript 中的类型参数

问题描述

我不完全确定解释我的问题的正确术语,所以这里有一个非常简化的例子,希望能解释我在寻找什么。

假设我有一个这样的通用类:

class MyStorage<T> {
  // … (omitted members that make class invariant)
  get(key: string): T {…}
  set(key: string, value: T): {…}
}

我故意使这个类保持不变,所以它不能被默默地强制到更广泛的范围内T

const stringStorage = new MyStorage<string>(…);
// Compiler error due to type mismatch. If this were allowed, unknownStorage
// could be used to put *anything* into stringStorage.
const unknownStorage: MyStorage<unknown> = stringStorage;

这很好用,并且可以捕获由T. 但是,有时能够保存对 MyStorage 实例的引用会很有用,T而不必知道它的确切类型。例如,

// Made up syntax. storage is a MyStorage of some erased type that extends U.
function readsFromStorage<U>(arg: U, storage: MyStorage<? extends U>) {
  // Valid. We know get() returns a type that extends U.
  const value: U = storage.get('mykey');
  // Compiler error. The erased T might be a narrow type than U.
  storage.set('mykey', arg);
}

或者:

// Made up syntax. storage is a MyStorage of some erased type extended by U.
function writesToStorage<U>(arg: U, storage: MyStorage<U extends ?>) {
  // Valid. We know that set() takes a type extended by U.
  storage.set('mykey', arg);
  // Compiler error. U might be narrower than the erased T type.
  const value: U = storage.get('mykey');
}

通常,当另一个泛型类想要存储对 a 的引用MyStorage<T>但不关心 的确切类型时,这将很有用T

这可以用今天的 TypeScript 来表达吗?如果没有,是否有现有的功能请求可以涵盖它?

标签: typescripttypescript-generics

解决方案


推荐阅读