错误TS2322:输入'{id:string; ''不能赋值给'ApiModelFilter <m>'

时间:2018-05-01 22:09:17

标签: typescript

我尝试定义一些过滤器,其中过滤器对象的键应该是从Model接口扩展的任何接口的键。

模型接口仅定义 id 属性。

当我尝试在通用类中使用ApiModelFilter类型时,只需将 id 和字符串定义为值,我就会从标题中获取错误。

我有什么想法可以解决这个问题吗?

我在使用Typescript v2.8.3和v2.6.2

时遇到此错误
interface Model {
  id: number;
}

export type ApiModelFilter<M extends Model> = {
  [P in keyof M]?: string
};

interface SomeModel extends Model {
  name: string;
  age: number;
  address: string;
}

class GenericModelHandlerClass<M extends Model> {
  get_instance(id: number): void {
    const the_filter: ApiModelFilter<M> = {
      id: 'test'
    };
    ...
  }
}

class SomeModelHandlerClass extends GenericModelHandlerClass<SomeModel> {
  ...
}

1 个答案:

答案 0 :(得分:4)

嗯,好像是一个TypeScript错误(或者至少是一个设计限制)。它与Microsoft/TypeScript#13442相关,其中某人感到惊讶的是,Partial<U>没有额外属性的对象字面值不能分配给Partial<T> T extends U。现在在那个的情况下,它不是一个错误:对于某些T[K]U[K]可能比K更窄,因此您无法将Partial<U>分配给Partial<T> T[K]。它不是问题的关键;这是价值观。

但是,在您的情况下,您并不关心U[K]{[K in keyof U]?: string}等值类型。你关心的只是。如果{[K in keyof T]?: string},它确实看起来像T extends U类型的字面值没有额外的属性应该可以赋值给keyof U类型的变量。 keyof T不能包含M中没有的任何值,因此它应该有效。 (在您的代码中,T的行为与Model类似,而U的行为与const the_filter = { id: 'test' } as ApiModelFilter<M>; // works 类似。)由于某种原因,编译器无法验证这一点。如果您认为此用例引人注目,则可能需要提交issue in GitHub

所以,解决方法。一种方法是做一个类型断言:

const the_filter: ApiModelFilter<M> = {};
the_filter.id = 'test'; // also works

你说你比编译器更了解,在这种情况下似乎是正确的。

或者您可以像这样重新安排代码:

the_filter

此处您最初将空对象分配给id,然后向其添加the_filter属性。编译器 识别出id具有可选的split属性,因此它允许您设置它。

希望其中一个适合你。祝你好运!