[英]Return inferred generic type
我想从类上的函数返回推断类型,但返回类型是扩展泛型类型,而不是函数的实际结果。 我想返回函数的推断类型。
我尝试了一些围绕包装和展开的方法,但无法让它们正常工作。
问题: newDocumentSet
的类型是IDocumentSet<DocumentTypes, IContact, never>
,而不是创建函数扩展参数中返回的类型
注意:我希望 create 函数返回扩展实例,而不是IDocumentSet
的接口。 似乎这个位 (create<TExtension extends IDocumentSet<TDocumentType, TEntity, TExtraExclusions>>) 搞砸了,我只是不确定如何强制执行扩展IDocumentSet<TDocumentType, TEntity, TExtraExclusions>
的返回类型但返回扩展类型不是IDocumentSet<TDocumentType, TEntity, TExtraExclusions>
。
目标:我想创建从创建函数返回扩展类的能力,而不是接口。
示例在下面,在这个小提琴中
我还发现了这篇关于包装和展开的帖子,但无法满足我的需要
此示例来自更大的代码库,已省略围绕TExtraExclusions
的代码以使此示例更小,但仍保留泛型。
export interface IDocumentSetBase<TDocumentType extends string> {
get DocumentType(): TDocumentType;
empty(): Promise<void>;
}
interface IDocumentSet<TDocumentType extends string, TEntity extends IDbRecord<TDocumentType>, TExtraExclusions extends (keyof TEntity) = never> extends IDocumentSetBase<TDocumentType> {
info(): boolean
}
interface IDbRecord<TDocumentType> extends IDbAdditionRecord<TDocumentType> {
readonly _id: string;
readonly _rev: string;
}
interface IDbAdditionRecord<T> {
readonly DocumentType: T;
}
export class DocumentSet<TDocumentType extends string, TEntity extends IDbRecord<TDocumentType>, TExtraExclusions extends (keyof TEntity) = never> implements IDocumentSet<TDocumentType, TEntity, TExtraExclusions> {
private _documentType: TDocumentType;
get DocumentType() { return this._documentType; }
constructor(documentType: TDocumentType) {
this._documentType = documentType;
}
info() {
return true;
}
async empty() {
}
}
class Builder<TDocumentType extends string, TEntity extends IDbRecord<TDocumentType>, TExtraExclusions extends (keyof TEntity) = never> {
private _documentType: TDocumentType;
constructor(documentType: TDocumentType) {
this._documentType = documentType;
}
create<TExtension extends IDocumentSet<TDocumentType, TEntity, TExtraExclusions>>(extend: (Instance: typeof DocumentSet<TDocumentType, TEntity, TExtraExclusions>, documentType: TDocumentType) => TExtension = w => (w as any) as TExtension) {
const result = extend(DocumentSet<TDocumentType, TEntity, TExtraExclusions>, this._documentType);
return result;
}
}
enum DocumentTypes {
Contacts = "Contacts"
}
interface IContact extends IDbRecord<DocumentTypes> {
firstName: string;
lastName: string;
address: string;
phone: string;
}
const builder = new Builder<DocumentTypes, IContact>(DocumentTypes.Contacts);
const newDocumentSet = builder.create((Instance, documentType) => {
return new class extends Instance {
constructor() {
super(documentType)
}
test() {
return "some value";
}
}
});
在您较短的示例中,您使用实例化表达式typeof DocumentSet<TDocumentType, TEntity>
来引用泛型类构造函数的类型,其泛型类型参数已使用参数TDocumentType, TEntity
指定。 也就是说,与new() => DocumentSet<TDocumentType, TEntity>
基本相同的类型(使用构造签名)。
如果将实例化表达式替换为等效类型:
create<TExtension extends IDocumentSet<TDocumentType, TEntity>>(
extend: (Instance: new () => DocumentSet<TDocumentType, TEntity>
) => TExtension = w => (w as any) as TExtension) {
return extend(DocumentSet);
}
然后,当您调用extend()
时,您会得到预期的推断:
myNewSet.someNewFunction(); // okay
我不确定为什么它不像你写的那样工作。 实例化表达式是新的(它们是在最新版本的 TypeScript 4.7 中引入的),所以我无法判断这种推理失败是语言错误、设计限制还是故意行为。 如果这很重要,有人可能想在 GitHub 中打开一个问题来询问它。 如果发生这种情况并且我们得到了答案,我们可以更新这篇文章。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.