我试图弄清楚是否可以使用具有可选属性的对象,并且在某些情况下,保证它们会在那里。有关我正在尝试做的一个例子:
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!");
}
这有点棘手,但最终我的目标是拥有一个'权限'对象及其要求,并通过一个布尔值获取相同的对象,该对象是否在通过函数运行后具有该权限
提前致谢!
答案 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"].has
和r["prop2"].has
都可以。