2017-06-05 73 views
1

想象我有一个查询类和这样的执行方法:我可以在Typescript中使用`keyof`来静态描述我想返回的这种类型的属性吗?

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} 

同样,我明白我只是写是不可能的,但我想必须有描述在某些方面,这些各种实例的方式,编译器将知道返回类型具有名称keyof q.queryName

任何想法?

+0

顺便说一句,'返回{[query.name]:真};' – SLaks

回答

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 

Live demo

但是,您不能证实实现该功能。

+0

这是真棒SLaks!谢谢!然而,我在这行上的Playground中发生错误:'{[Object.keys(query.queryName)[0]]:true};'Type {[x:string]:boolean}不能分配给Result 。我错过了明显的东西吗? – Taytay

+0

我知道没有办法向TypeScript编译器证明您有正确的名称。例如,如果你传递一个包含两个属性的对象呢? – SLaks

+0

好点。看起来像一个演员阵容可能是去的方式:功能 返回<结果> {[Object.keys(query.queryName)[0]]:} – Taytay

相关问题