我使用FeathersJS(这很棒)但不幸的是,它不是用TypeScript编写的,因此必须单独编写和维护打字。
Here是打字文件。其中有Service<T>
类型,如下所示:
export type Service<T> = ServiceOverloads<T> & ServiceAddons<T> & ServiceMethods<T>;
ServiceOverloads<T>
看起来像:
export interface ServiceOverloads<T> {
create(data: Array<Partial<T>>, params?: Params): Promise<T[]>;
create(data: Partial<T>, params?: Params): Promise<T>;
patch(id: NullableId, data: Pick<T, keyof T>, params?: Params): Promise<T>;
}
和ServiceMethods<T>
看起来像:
export interface ServiceMethods<T> {
find(params?: Params): Promise<T[] | Paginated<T>>;
get(id: Id, params?: Params): Promise<T>;
create(data: Partial<T> | Array<Partial<T>>, params?: Params): Promise<T | T[]>;
update(id: NullableId, data: T, params?: Params): Promise<T>;
patch(id: NullableId, data: Partial<T>, params?: Params): Promise<T>;
remove(id: NullableId, params?: Params): Promise<T>;
}
正如您所看到的,create
和patch
方法应该发生冲突,因为它们会生成相同的JavaScript。
为什么类型别名Service<T>
会编译,但在尝试实现时会因为方法冲突而失败?如果我完全从每个接口复制方法并提供存根实现,那应该不起作用吗?
答案 0 :(得分:3)
在TypeScript中,具有功能签名的intersection类型对应于overloading这些功能。来自相关的GitHub issue introducing intersection types:
调用和构建签名
如果
A
有签名F
且B
有签名G
,则A & B
有签名F
和{{1}按此顺序(签名的顺序对于重载解析而言很重要)。除签名顺序外,G
和A & B
类型相同。
在您的情况下,B & A
实际上是
ServiceOverloads<T> & ServiceMethods<T>
因此您需要在{
create(data: Array<Partial<T>>, params?: Params): Promise<T[]>;
create(data: Partial<T>, params?: Params): Promise<T>;
create(data: Partial<T> | Array<Partial<T>>, params?: Params): Promise<T | T[]>;
patch(id: NullableId, data: Pick<T, keyof T>, params?: Params): Promise<T>;
patch(id: NullableId, data: Partial<T>, params?: Params): Promise<T>;
find(params?: Params): Promise<T[] | Paginated<T>>;
get(id: Id, params?: Params): Promise<T>;
update(id: NullableId, data: T, params?: Params): Promise<T>;
remove(id: NullableId, params?: Params): Promise<T>;
}
和create()
重载方法而不是单签名方法的情况下实现它。这是一个示例:
patch()
希望有所帮助;祝你好运!