2017-06-05 21 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

相關問題