TypeScript Version: 2.8.1
Search Terms:
condition types, unions, optional, undefined
Code
interface StringOption{
type: "string";
}
interface NumberOption{
type: "number";
}
interface ISampleObject {
requiredParam: string,
optionalParam?: number
}
type MappedOptions<T> = {
readonly [P in keyof T]: T[P] extends undefined ? StringOption : NumberOption;
}
const mappedObject: MappedOptions<ISampleObject> = {
requiredParam: {type: "number"},
optionalParam: {type: "string"}
}
Expected behavior:
as optionalParam is optional you should be able to switch on that in conditional type so that when mapped optionalParam is of type StringOption and requiredParam is of type NumberOption.
Actual behavior:
both types are of type NumberOption as neither extend undefined. A syntax is needed to say that a type includes a type in a union I suppose and as far as I know this is not yet available.
Playground Link:
Playground link
I guess you want undefined extends T[P] ? NumberOption : StringOption.
you can also remove the optionality later on using -?:
type MappedOptions<T> = {
readonly [P in keyof T]-?: undefined extends T[P] ? NumberOption : StringOption
}
I was just about to reply and say that still doesn't work but string null checks wasn't turned on.
Now does exactly what I want. Thanks
export type OptionalPropertyNames<T> = {
[K in keyof T]-?: undefined extends T[K] ? K : never
}[keyof T];
export type RequiredPropertyNames<T> = {
[K in keyof T]-?: undefined extends T[K] ? never : K
}[keyof T];
export type OptionalProperties<T> = Pick<T, OptionalPropertyNames<T>>
export type RequiredProperties<T> = Pick<T, RequiredPropertyNames<T>>
I arrived looking for these, and was able to piece it together based on the great information above.
Should undefined extends work outside mapped types? See here
edit: Nevermind, looks like this was fixed in 3.1.0
I'm looking for a way to create optional props conditionally, let's say, if prop A is defined make prop B optional, or if prop B is defined then prop A is optional, I'm wondering if this is the case of this solution and if so, how to use it?
Most helpful comment
I'm looking for a way to create optional props conditionally, let's say, if prop
Ais defined make propBoptional, or if propBis defined then propAis optional, I'm wondering if this is the case of this solution and if so, how to use it?