簡體   English   中英

TypeScript泛型:“類型不可分配給類型T”

[英]TypeScript Generics: 'type is not assignable to type T'

我已經建立了一個工廠,它將創建某些類的實例。 我想使用泛型來確保返回的所有對象均來自擴展抽象類的子類。

我認為以下所示的createInstance方法的邏輯可以描述為'createInstance()將返回類型T ,該類型T被約束為擴展Animal的類。

如您所見,Lion擴展了Animal,但是我仍然得到編譯器警告type Lion is not assignable to type T

abstract class Animal {
    abstract makeSound(): void;
}

class Bear extends Animal {
    public makeSound() {
        console.log('growl');
    }
}

class Lion extends Animal {
    public makeSound() {
        console.log('roar');
    }
}

function createInstance<T extends Animal>(type: string): T {
    switch(type) {
        case 'bear':
            return new Bear(); // 'type Bear is not assignable to type T'
        case 'lion':
            return new Lion(); // 'type Lion is not assignable to type T'
    }
}

createInstance().makeSound();

我在TypeScript泛型文檔的末尾讀到:

使用泛型在TypeScript中創建工廠時,有必要通過其構造函數來引用類類型。 例如,

 function create<T>(c: {new(): T; }): T { return new c(); } 

但是我真的不想在可能的情況下將類構造函數傳遞給函數,並且想了解為什么我首先得到了not assignable to type T消息。

謝謝

如果您的函數始終返回Lion則其結果類型不是真正的泛型。 例如,您可以編寫create<Tiger>()而您的函數仍將返回Lion 真正的泛型函數將返回一個接受泛型參數的值。

發現時,您可以將構造函數作為參數傳遞:

function create<T>(c: {new(): T; }): T {
    return new c();
}

或者,您可以使函數不通用,並使其返回AnimalLion 如果您具有根據參數值確定返回類型的邏輯,則可能會有更多的重載:

// Public signatures, we tie function parameter values to return value for specific types
function createInstance(type: "Lion"): Lion 
function createInstance(type: "Tiger"): Tiger 
// Private signature, not visible from outside
function createInstance(type: "Lion" | "Tiger"): Animal {
    if(type === "Lion") {
        return new Lion();
    }
    else if(type === "Tiger") {
        return new Tiger(); 
    }
}
let tiger = createInstance("Tiger"); // will be typed as Tiger
let lion = createInstance("Lion");// will be typed as Lion
let err = createInstance("Lama");// will be an error since the function does not know how to create a Lama

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM