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
}
Update 2018-10: @MattMcCutchen has figured out that it is possible to detect
readonlyfields (invalidating the struck-out passage below), as shown in this answer. Here is a way to build it:If you want to extract the writable fields from an interface, you can use the above
WritableKeysdefinition andPicktogether:Hooray!
For `readonly`, I don't think you can extract those. I've [looked at this issue before](https://github.com/Microsoft/TypeScript/issues/13257#issuecomment-308528175) and it wasn't possible then; and I don't think anything has changed.Since the compiler doesn't soundly check
readonlyproperties, 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:But you can't. There's some interesting discussion about this in a GitHub issue originally named "
readonlymodifiers 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: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, andabstract, but I would doubt it. It happens that theprivateandprotectedclass properties can be excluded pretty easily, since they are not present inkeyof:But extracting the
privateorprotectedproperties might be impossible, for the same reason that excluding them is so easy:keyof Foodoesn't have them. And for all of these includingabstract, 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.