-
Notifications
You must be signed in to change notification settings - Fork 12.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Type to invert optionality of properties #16173
Comments
Interesting use case for me, but how about this way: type Optional<T> = {
[key in keyof T]?: T[key];
}
interface DefaultProps {
point: { x: number, y: number };
}
interface SomeProps extends Optional<DefaultProps> {
name: string;
}
var x: SomeProps = {
name: 'abc' // error if missed
};
var y: DefaultProps = {
point: { x: 0, y: 0 } // error if missed
}; |
Yes that will work too ... but in the end u need to define two separated tytes... |
@mhegazy i dont think this is a dupe,,. both #13224 and #15012 are trying to make all properties required: type Original = {
first: any;
second?: any;
}
type Result = {
first: any;
second: any;
} im trying to 'flip' required flag on each property: type Original = {
first: any;
second?: any;
}
type Result = {
first?: any; // because Original.first was required
second: any; // because Original.second was not required
} but if u really think this is a dupe fell free to close it ... |
do you have a scenario where flipping optionality is required? |
@mhegazy look at my initial message ... bacically to have react component defaults required for optional props. BTW: I think that i can achieve it by this code: (not tested) module ISomeProps {
export interface Req {
first: any;
}
export interface Def {
second:any;
}
}
interface ISomeProps extends ISomeProps.Req, Partial<ISomeProps.Def> {}
class Some extends React.Component<ISomeProps, never> {
static defaultProps: Partial<ISomeProps.Req> & ISomeProps.Def = {
second: 42
};
...
} |
You can do this with existing TS features. We first need two helpers. type OptionalKeys<T> = {
[K in keyof T]-?: undefined extends { [K2 in keyof T]: K2 }[K] ? K : never
}[keyof T]
type RequiredKeys<T> = Exclude<keyof T, OptionalKeys<T>> The That is, given: type Original = {
first: string;
second?: number;
req: any;
opt?: any;
unioned: string | undefined;
} Then With these helpers, then type Invert<T> = {
[K in OptionalKeys<T>]-?: NonNullable<T[K]>
} & {
[K in RequiredKeys<T>]+?: T[K]
} This almost gives you the exact behavior that the OP asks for, but TS will display the properties as an intersection. You can merge the intersection back into a single object type with a mapped type that does nothing.. type MergeIntersection<T> = { [K in keyof T]: T[K] }
type OptionalKeys<T> = {
[K in keyof T]-?: undefined extends { [K2 in keyof T]: K2 }[K] ? K : never
}[keyof T]
type RequiredKeys<T> = Exclude<keyof T, OptionalKeys<T>>
type Invert<T> = MergeIntersection<{
[K in OptionalKeys<T>]-?: NonNullable<T[K]>
} & {
[K in RequiredKeys<T>]+?: T[K]
}>
type Original = {
first: string;
second?: number;
req: any;
opt?: any;
unioned: string | undefined;
}
type InvertedTest = Invert<Original>;
// On hover shows:
// type InvertedTest = {
// second: number;
// opt: any;
// first?: string | undefined;
// req?: any;
// unioned?: string | undefined;
// } |
We're not adding new utility types to the lib. |
Why? The |
People don't agree with the "right" definition of any given utility type and get upset that we didn't use their version |
add new mapped type:
Invert<T>
... I do not know, how to explain it in english, so i use code:example usage: react defaultProps - to ensure, that all optional props are declared.
priority: really low, almost negative :) - but if it can be done and isnt too hard ...
The text was updated successfully, but these errors were encountered: