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
A
is defined make propB
optional, or if propB
is defined then propA
is optional, I'm wondering if this is the case of this solution and if so, how to use it?