Using the new conditional types in TypeScript (or maybe another technique), is there a way to pick only certain properties from an interface based on their modifiers? For example, having...
interface I1 {     readonly n: number     s: string }   I would like to create a new type based on the previous one which looks like this:
interface I2 {     s: string } 
                You can use mapping modifiers to change a readonly property to mutable in TypeScript, e.g. -readonly [Key in keyof Type]: Type[Key] . You can remove the readonly modifier by prefixing the readonly keyword with a minus - .
In TypeScript, pick is used to take the certain objects of an already defined interface to create a new model.
What is a type in TypeScript. In TypeScript, a type is a convenient way to refer to the different properties and functions that a value has. A value is anything that you can assign to a variable e.g., a number, a string, an array, an object, and a function.
A mapped type is a generic type which uses a union of PropertyKey s (frequently created via a keyof ) to iterate through keys to create a type: type OptionsFlags < Type > = { [ Property in keyof Type ]: boolean; };
Update 2018-10: @MattMcCutchen has figured out that it is possible to detect readonly fields (invalidating the struck-out passage below), as shown in this answer.  Here is a way to build it:
type IfEquals<X, Y, A=X, B=never> =   (<T>() => T extends X ? 1 : 2) extends   (<T>() => T extends Y ? 1 : 2) ? A : B;  type WritableKeys<T> = {   [P in keyof T]-?: IfEquals<{ [Q in P]: T[P] }, { -readonly [Q in P]: T[P] }, P> }[keyof T];  type ReadonlyKeys<T> = {   [P in keyof T]-?: IfEquals<{ [Q in P]: T[P] }, { -readonly [Q in P]: T[P] }, never, P> }[keyof T];   If you want to extract the writable fields from an interface, you can use the above WritableKeys definition and Pick together:
interface I1 {     readonly n: number     s: string }  type I2 = Pick<I1, WritableKeys<I1>>;  // equivalent to { s: string; }   Hooray!
 For readonly, I don't think you can extract those.  I've looked at this issue before and it wasn't possible then; and I don't think anything has changed.
Since the compiler doesn't soundly check readonly properties, you can always assign a {readonly n: number} to a {n: number} and vice-versa.  And therefore the obvious TSv2.8 conditional type check doesn't work.  If, for example, {n: number} were not considered assignable to {readonly n: number} then you could do something like:
// does not work, do not try this type ExcludeReadonlyProps<T> = Pick<T,   { [K in keyof T]-?:     ({ readonly [P in K]: T[K] } extends { [P in K]: T[K] } ? never : K)   }[keyof T]>  type I2 = ExcludeReadonlyProps<I1> // should be {s: string} but is {} 🙁   But you can't.  There's some interesting discussion about this in a GitHub issue originally named "readonly modifiers are a joke".  
Sorry! Good luck.
For optional properties, you can indeed detect them and therefore extract or exclude them.  The insight here is that {} extends {a?: string}, but {} does not extend {a: string} or even {a: string | undefined}.  Here's how you could build a way to remove optional properties from a type:
type RequiredKeys<T> = { [K in keyof T]-?:   ({} extends { [P in K]: T[K] } ? never : K) }[keyof T]  type OptionalKeys<T> = { [K in keyof T]-?:   ({} extends { [P in K]: T[K] } ? K : never) }[keyof T]  type ExcludeOptionalProps<T> = Pick<T, RequiredKeys<T>>  type I3 = {    a: string,    b?: number,    c: boolean | undefined }  type I4 = ExcludeOptionalProps<I3>; // {a: string; c: boolean | undefined} 🙂   So that's good.
Finally, I don't know if you want to be able to do stuff with the class-only property modifiers like public, private, protected, and abstract, but I would doubt it.  It happens that the private and protected class properties can be excluded pretty easily, since they are not present in keyof:
class Foo {   public a = ""   protected b = 2   private c = false } type PublicOnly<T> = Pick<T, keyof T>; // seems like a no-op but it works type PublicFoo = PublicOnly<Foo>; // {a: string} 🙂   But extracting the private or protected properties might be impossible, for the same reason that excluding them is so easy: keyof Foo doesn't have them.  And for all of these including abstract, you can't add them to properties in type aliases (they are class-only modifiers), so there's not much I can think of to do to touch them.
Okay, hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With