我有以下代码,该代码在TypeScript 3.0.1中有效,但在3.1.3中给出了编译错误。如果可能的话,我想知道3.1。+中的哪些更改使代码无效,或者这可能是编译器错误。
export interface Entity {
id: number | string;
}
export type IdOf<E extends Entity> = E['id'];
export interface EntityState<E extends Entity> {
ids: IdOf<E>[];
entities: { [key: string]: E, [key: number]: E };
}
export function getAllEntities<E extends Entity>(state: EntityState<E>): E[] {
const { ids, entities } = state;
return ids.map(id => entities[id]);
}
export function getEntity<E extends Entity>(id: IdOf<E>, state: EntityState<E>): E | undefined {
const { ids, entities } = state;
if (!ids.includes(id)) {
return undefined;
}
return entities[id];
}
正如我所说,它在3.0.1中可以正常编译,但是在3.1.3中却出现以下错误:
BUILD ERROR
projects/entity/src/lib/entity-state.utils.ts(13,5): error TS2322: Type '{ [key: string]: E; [key: number]: E; }[E["id"]][]' is not assignable to type 'E[]'.
Type '{ [key: string]: E; [key: number]: E; }[E["id"]]' is not assignable to type 'E'.
Type 'Entity' is not assignable to type 'E'.
projects/entity/src/lib/entity-state.utils.ts(23,5): error TS2322: Type '{ [key: string]: E; [key: number]: E; }[E["id"]]' is not assignable to type 'E | undefined'.
Type 'Entity' is not assignable to type 'E'.
Type '{ [key: string]: E; [key: number]: E; }[E["id"]]' is not assignable to type 'E'.
Type 'Entity' is not assignable to type 'E'.
这两个错误分别对应于两个函数的return语句。
编辑。为了完整起见,我只想提一下我打算让用户为其域类型创建Entity
和EntityState
的子接口,将id
覆盖为限制性更强的类型。这就是IdOf
类型很重要的原因。例如,
interface Task extends Entity {
id: string;
due: Date;
title: string;
}
interface TaskState extends EntityState<Task> {
// Inherits EntityState#ids as string[]
currentTask?: string;
}
答案 0 :(得分:1)
将type
更改为interface
可以解决此问题,类型不支持扩展,如果您需要继承来工作,请始终使用interface
,它在更早的时候就起作用了,也许他们在通用类型检查中添加了更严格的规则
export interface Entity {
id: number | string;
}
export type IdOf<E extends Entity> = E['id'];
export interface EntityState<E extends Entity> {
ids: IdOf<E>[];
entities: { [key: string]: E, [key: number]: E };
}
export function getAllEntities<E extends Entity>(state: EntityState<E>): E[] {
const { ids, entities } = state;
return ids.map(id => entities[id]) as E[];
}
export function getEntity<E extends Entity>(id: IdOf<E>, state: EntityState<E>): E | undefined {
const { ids, entities } = state;
if (!ids.includes(id)) {
return undefined;
}
return entities[id] as E;
}