我正在尝试编写一个函数来验证属性是否具有泛型类型并返回其值。
// tslint:disable-next-line no-any -> must be any, or typescript can't infer the return value
function ensureProperty<T>(obj: object, propertyName: string, guard: (obj: any | undefined) => obj is T): T {
const val = obj[propertyName];
if (!guard(val)) {
throw new Error(propertyName);
}
return val;
}
哪种方法效果很好,但是我想知道是否有一种方法可以告诉打字稿对象obj
应该是具有指定名称属性的类型。
const obj = { example: ""};
ensureProperty(obj, "notexisting", Guard.isString); // this should result in a type error
ensureProperty(obj, "example", Guard.isString); // this should work
我在想类似的事情:(我知道这行不通,我只是在想这可能会澄清我的意图...)
function ensureProperty<T>(obj: {[key == propertyName]: T|undefined}, propertyName: string, ...
但是,恐怕没有这样的语言构造了吗?
答案 0 :(得分:1)
您可以做类似的事情
function ensureProperty<T, K>(obj: K, propertyName: keyof K, guard: (obj: any | undefined) => obj is T): T {
const val = obj[propertyName];
if (!guard(val)) {
throw new Error(propertyName.toString());
}
return val;
}
结果
const obj = { example: ""};
ensureProperty(obj, "notexisting", Guard.isString); // Argument of type '"notexisting"' is not assignable to parameter of type '"example"'.
ensureProperty(obj, "example", Guard.isString); // OK
请注意,现在propertyName
无法直接传递给Error
构造函数,因此我们必须先将其转换为字符串。