打字稿:根据另一个键入一个参数

时间:2020-02-27 09:36:03

标签: typescript

参观这个游乐场:Playground

export interface IProduct {
    productId: number;
}

export interface ICompany {
    companyId: number;
}

function click(type: 'product', entity: IProduct): string;
function click(type: 'company', entity: ICompany): string;
function click<T>(type: 'product' | 'company', entity: T) {
    if (type === 'product') {
        return 'product ' + entity.productId;
    } else if (type === 'company') {
        return 'company ' + entity.companyId;
    }

    throw new Error('wrong input');
}

click('product', { productId: 123 });

如何使打字稿理解,如果第一个if的值为true,那么第二个参数为IProduct

2 个答案:

答案 0 :(得分:2)

您可以将参数键入为元组的并集,但这很丑陋,因为无法使用解构(打字稿将释放类型关系):

res.json([])

Playground

答案 1 :(得分:0)

一种可行的解决方案(但不是一个好的解决方案):

function click(type: 'product', entity: IProduct): string;
function click(type: 'company', entity: ICompany): string;
function click<T extends IProduct | ICompany>(type: 'product' | 'company', entity: T) {
    if (type === 'product' && assertType(type, entity)) {
        return 'product ' + entity.productId;
    } else if (type === 'company' && assertType(type, entity)) {
        return 'company ' + entity.companyId;
    }

    throw new Error('wrong input');
}

function assertType(type: 'product', entity: IProduct | ICompany): entity is IProduct;
function assertType(type: 'company', entity: IProduct | ICompany): entity is ICompany;
function assertType(type: 'product' | 'company', entity: IProduct | ICompany): entity is IProduct | ICompany {
    return entity && type === "product" || type === "company";
}

Playground Link

(在我看来)好得多的更好解决方案:

function click(entity: IProduct | ICompany) {
    // here: (parameter) entity: IProduct | ICompany

    if ("productId" in entity) {
        // here: (parameter) entity: IProduct
        return `product ${entity.productId}`;

    } else if ("companyId" in entity) {
        // here: (parameter) entity: ICompany
        return `company ${entity.companyId}`;
    }

    throw new Error('wrong input');
}

Playground Link