TypeScript – extract interface members only – possible?

Since typescript interfaces don’t exist at runtime, we can’t use them to guide any runtime behavior, just compile-time type checking. We can however create an object that has the same properties as the interface (with all the properties of type true for example to simplify initialization) and make the compiler trigger an error if this object has any more or less fields then the interface. We can use this object as the guide to what properties we extract:

function extract<T>(properties: Record<keyof T, true>){
    return function<TActual extends T>(value: TActual){
        let result = {} as T;
        for (const property of Object.keys(properties) as Array<keyof T>) {
            result[property] = value[property];
        }
        return result;
    }
}

interface ISpecific { A: string; B: string; }
const extractISpecific = extract<ISpecific>({ 
    // This object literal is guaranteed by the compiler to have no more and no less properties then ISpecific
    A: true,
    B: true
})
class Extended implements ISpecific { public A: string = '1'; public B: string = '2'; public C: string = '3'; }

let someObject = new Extended(); 
let subset = extractISpecific(someObject); 

Leave a Comment