2017-03-26 23 views
3

假設我有這樣的類和接口如何使用接口獲取對象的子集?

class User { 
    name: string; 
    age: number; 
    isAdmin: boolean; 
} 

interface IUser { 
    name: string; 
    age: number; 
} 

然後我從什麼地方

const data = { 
    name: "John", 
    age: 25, 
    isAdmin: true 
} 

我想用IUser於子集data並刪除isAdmin財產這樣

let user = subset<IUser>(data); 
// user is now { name: "John", age: 25 } 
// can safely insert user in the db 
得到這個JSON對象

我的問題是如何在TypeScript中實現該功能?

function subset<T>(obj: object) { 
    // keep all properties of obj that are in T 
    // keep, all optional properties in T 
    // remove any properties out of T 
} 

回答

2

有沒有辦法做到這一點是優於:

function subset(obj: IUser) { 
    return { 
     name: obj.name, 
     age: obj.age 
    } 
} 

接口不運行時存在(這是當subset調用),所以你不能使用IUser接口的打字稿知道哪些屬性是需要的,哪些不是。

你可以使用一個類做「生存」的編譯過程

class IUser { 
    name: string; 
    age: number; 
} 

編譯爲:

var IUser = (function() { 
    function IUser() { 
    } 
    return IUser; 
}()); 

正如你所看到的,屬性不是的一部分編譯後的輸出,因爲類成員只添加到實例而不添加到類中,所以即使是一個類也不會幫助你。

您可以使用修飾符和元數據(more on that here),但這聽起來像是您的方案的矯枉過正。

了一個更通用subset功能的另一種選擇是:

function subset<T>(obj: T, ...keys: (keyof T)[]) { 
    const result = {} as T; 

    keys.forEach(key => result[key] = obj[key]); 
    return result; 
} 
let user1 = subset(data, "name", "age"); 
let user2 = subset(data, "name", "ag"); // error: Argument of type '"ag"' is not assignable to parameter of type '"name" | "age" | "isAdmin"' 
相關問題