2017-03-26 6 views
3

내가 내가 IUser를 사용하여 data을 부분 집합이인터페이스를 사용하여 객체의 하위 집합을 가져 오는 방법은 무엇입니까?

let user = subset<IUser>(data); 
// user is now { name: "John", age: 25 } 
// can safely insert user in the db 
처럼 isAdmin 속성을 제거 할 곳

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

에서이 JSON 객체를 가져

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

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

그리고이 클래스 및 인터페이스가 있다고 가정

제 질문은 어떻게 그 기능을 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 인터페이스를 사용할 수 없습니다 타이프 라이터 어떤 속성이 필요하고 어떤 속성이 필요하지 않은지 알고 있어야합니다. 당신이 볼 수 있듯이

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

는 속성이 포함되지 않은 : 당신은 수행하는 클래스를 사용할 수 있습니다

가 컴파일 과정 하지만 "생존"

:에

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

은 컴파일 클래스 멤버는 인스턴스가 아니라 클래스에 추가되기 때문에 컴파일 된 결과가 나오므로 클래스조차도 도움이되지 않습니다.

데코레이터와 메타 데이터 (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"'