Typescript泛型对象 - 追加属性

时间:2016-06-12 20:16:07

标签: typescript

我试图弄清楚是否可以使用具有可选属性的对象,并且在某些情况下,保证它们会在那里。有关我正在尝试做的一个例子:

interface PermissionsAvailable {
    [key: string]: {
        role?: number;
        feature?: string;
        has?: boolean;
    }
}

export function verifyPermissions<T extends PermissionsAvailable>(p: T): T & { [key: string]: { has: boolean }} {
    for (let i in p) {
        p[i].has = true;
    }

    return p as T & { [key: string]: { has: boolean }};
}

const r = verifyPermissions({prop1: {role: 2}});

if (r.prop1.has) {
    console.log("HAS PERMISSION!");
}

这有点棘手,但最终我的目标是拥有一个'权限'对象及其要求,并通过一个布尔值获取相同的对象,该对象是否在通过函数运行后具有该权限

提前致谢!

编辑: Link on TS playground with the problem

1 个答案:

答案 0 :(得分:2)

如果我理解你,那么我认为它应该是:

function test<T extends PermissionSackProps>(p: T): T & { [key: string]: { has: boolean }} {
    for (let i in p) {
        p[i].has = true;
    }

    return p as T & { [key: string]: { has: boolean } };
}

T & { T: { has: boolean } }没有意义,因为索引是相同的,而不是T类型。

修改

如果您阅读Indexable Types docs,您会发现需要使用括号而不是点来访问对象中的项目。

在你的code in playground中,你有两个问题:

if (r.prop1.has) {
    console.log("HAS PERMISSION!");
}

应该是

if (r["prop1"].has) {
    console.log("HAS PERMISSION!");
}

const r = verifyPermissions({ prop1: { role: 2 } });

应该是:

const r = verifyPermissions({ prop1: { role: 2 } } as PermissionsAvailable);

如果您将鼠标指向游乐场中的r(在您的代码中),您会看到它的'type:

const r: { [x: string]: { role: number; }; prop1: { role: number; }; } & { [key: string]: { has: boolean; }; }

这就是原因:

if (r["prop1"].has) {
    console.log("HAS PERMISSION!");
}

会引发错误,但不会:

if (r["prop2"].has) {
    console.log("HAS PERMISSION!");
}

my code中的r类型为:

const r: PermissionsAvailable & { [key: string]: { has: boolean; }; }

然后r["prop1"].hasr["prop2"].has都可以。

modified code in playground