-
Notifications
You must be signed in to change notification settings - Fork 12.5k
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
Add a Spread/Assign utility types -- Better type for Object.assign(), and spread type operator #51761
Comments
See #39522 (comment):
|
I think this is a bit different in that it greatly improves the types for |
For |
The Assign utility type I've provided here fixes the issue found: #45215 (comment). I think that this proposal is worth consideration |
Please consider it considered. We don't add utility types to the lib, and don't really want to mess with |
https://www.typescriptlang.org/docs/handbook/utility-types.html ? The spread type operator is a neat Idea type A = { a: string; };
type B = { b?: number ; };
type AB = { ...A; ...B; };
// ^? { a: string; b?: number; } My type OptionalKeys<T> = Exclude<
{
[K in keyof T]: T extends Record<K, T[K]> ? never : K;
}[keyof T],
undefined
>;
type RequiredKeys<T> = Exclude<keyof T, OptionalKeys<T>>;
type Spread<A extends any[]> = A extends [infer Acc]
? Acc
: A extends [infer Acc, infer Next]
? {
// props from Acc that aren't in Next
[K in Exclude<keyof Acc, keyof Next>]: Acc[K];
} & {
// optional props from Next that overlap props from Acc
[K in Extract<keyof Acc, OptionalKeys<Next>>]?: Acc[K] | Next[K];
} & {
// required props from Next that overlap props from Acc
[K in Extract<keyof Acc, RequiredKeys<Next>>]: Next[K];
} & {
// props from Next that aren't in Acc
[K in Exclude<keyof Next, keyof Acc>]: Next[K];
} extends infer U
? {
[P in keyof U]: U[P];
}
: never
: A extends [infer Acc, infer Next, ...infer Rest]
? Spread<[Spread<[Acc, Next]>, ...Rest]>
: never; Then we could use type AB = { ...A; ...B; };
type ABC = { prop1: string; ...A; prop2: string; ...B; prop3: string; }; Just becomes syntactic sugar for: type AB = Spread<[A, B]>;
type ABC = Spread<[{ prop1: string; }, A, { prop2: string; }, B, { prop3: string; }]>; Though I think proper spread type operator should work how the JS object spread operator works so there are a few cases where If proper spread type operator was a thing, I still think the interface ObjectConstructor {
assign<T extends {}, S extends any[]>(target: T, ...sources: S): Spread<[T, ...S]>;
} instead of interface ObjectConstructor {
assign<T extends {}, S1>(target: T, s1: S1): { ...T; ...S1; };
assign<T extends {}, S1, S2>(target: T, s1: S1, s2: S2): { ...T; ...S1; ...S2; };
assign<T extends {}, S1, S2, S3>(target: T, s1: S1, s2: S2, s3: S3): { ...T; ...S1; ...S2; ...S3; };
assign(target: object, ...sources: any[]): any;
} Using |
This issue has been marked as "Declined" and has seen no recent activity. It has been automatically closed for house-keeping purposes. |
lib Update Request
?:
syntax{ a: string } & { b: string }
becomes{ a: string, b: string }
)TypeScript Playground
Sample Code
OptionalKeys, RequiredKeys:
FlattenIntersection:
Assign:
Assign Usage:
The text was updated successfully, but these errors were encountered: