我尝试定义一些过滤器,其中过滤器对象的键应该是从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> {
...
}
答案 0 :(得分:4)
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
属性,因此它允许您设置它。
希望其中一个适合你。祝你好运!