[英]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.