Wander Wang
Wander Wang

Reputation: 451

how to remove properties via mapped type in TypeScript

Here is the code

class A {
    x = 0;
    y = 0;
    visible = false;
    render() {

    }
}

type RemoveProperties<T> = {
    readonly [P in keyof T]: T[P] extends Function ? T[P] : never//;
};


var a = new A() as RemoveProperties<A>
a.visible // never
a.render() // ok!

I want to remove " visible / x / y " properties via RemoveProperties ,but I can only replace it with never

Upvotes: 42

Views: 21382

Answers (2)

ford04
ford04

Reputation: 74490

TS 4.1

You can use as clauses in mapped types to filter out properties in one go:

type Methods<T> = { [P in keyof T as T[P] extends Function ? P : never]: T[P] };
type A_Methods = Methods<A>;  // { render: () => void; }

When the type specified in an as clause resolves to never, no property is generated for that key. Thus, an as clause can be used as a filter [.]

Further info: Announcing TypeScript 4.1 - Key Remapping in Mapped Types

Playground

Upvotes: 75

Titian Cernicova-Dragomir
Titian Cernicova-Dragomir

Reputation: 249486

You can use the same trick as the Omit type uses:

// We take the keys of P and if T[P] is a Function we type P as P (the string literal type for the key), otherwise we type it as never. 
// Then we index by keyof T, never will be removed from the union of types, leaving just the property keys that were not typed as never
type JustMethodKeys<T> = ({[P in keyof T]: T[P] extends Function ? P : never })[keyof T];  
type JustMethods<T> = Pick<T, JustMethodKeys<T>>; 

Upvotes: 60

Related Questions