想象一下,我有一个查询类和执行方法,如下所示:
class Query {
name: string;
sql: string;
}
function execute(query: Query): any{
let retVal = {};
retVal[query.name] = true;
return retVal;
}
q = new Query();
q.name = "thisIsMyQueryName";
let result = execute(q); // Returns: {thisIsMyQueryName: true}
// `typeof result` is still `any` of course, but I'd like it to be:
// {thisIsMyQueryName: boolean}
在这种情况下,我返回的对象具有基于我传入其中的类的实例的形状。显然,由于查询的“名称”在运行时可能会有所不同,因此我无法告诉编译器,因此它知道返回的对象将具有名为“thisIsMyQueryName”的属性。
然而,我认为我可以采取一些措施来使其更加静态地进行分析。我们有很多这些“查询”对象,当我们在代码中实例化它们时,我们知道它们的名字。我正在试验key of
的不同咒语,我有一些很有希望的事情,但我对此并不满意。
能够做到这一点是理想的:
let q = {
sql: "",
queryName: {
thisIsMyQueryName: ""
}
}
let result = execute(q); // Returns: {thisIsMyQueryName: true}
// typeof result == {thisIsMyQueryName: boolean}
同样,我意识到我刚写的内容是不可能的,但我认为必须有一种方法以某种方式描述这些各种实例,编译器将知道返回类型具有名为{{1的属性}}
有什么想法吗?
答案 0 :(得分:1)
您可以通过.queryName
类型参数并在该参数上使用keyof
来执行此操作:
class Query<TName> {
queryName: TName
sql: string;
}
type Result<TName> = {
[P in keyof TName]: boolean
}
function execute<TName>(query: Query<TName>): Result<TName> {
return { [Object.keys(query.queryName)[0]]: true };
}
const q = {
sql: "",
queryName: {
thisIsMyQueryName: ""
}
};
const result = execute(q);
const b = result.thisIsMyQueryName; // boolean
但是,您无法证明实现该功能。