通用行为在3.0.1和3.1.3之间的变化

时间:2018-10-14 02:17:20

标签: typescript

我有以下代码,该代码在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语句。

编辑。为了完整起见,我只想提一下我打算让用户为其域类型创建EntityEntityState的子接口,将id覆盖为限制性更强的类型。这就是IdOf类型很重要的原因。例如,

interface Task extends Entity {
    id: string;
    due: Date;
    title: string;
}

interface TaskState extends EntityState<Task> {
    // Inherits EntityState#ids as string[]
    currentTask?: string;
}

1 个答案:

答案 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;
}