Skip to content
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

Eliminate need for in-repo just-extend types #301

Open
Silic0nS0ldier opened this issue Feb 25, 2021 · 1 comment
Open

Eliminate need for in-repo just-extend types #301

Silic0nS0ldier opened this issue Feb 25, 2021 · 1 comment

Comments

@Silic0nS0ldier
Copy link
Member

Ideally we'll defer to DefinityTyped or get it merged into the project in question directly (unlikely given past dialogue angus-c/just#126). Up until now technical limitations have blocked this.

Potential answer may be found in https://stackoverflow.com/a/49683575/4728587 however.

@Silic0nS0ldier
Copy link
Member Author

Closer, but a TS performance bail out occurs at 8 inputs.

// Type definitions for just-extend 4.1
// Project: https://github.com/angus-c/just#readme
// Definitions by: Peter Safranek <https://github.com/pe8ter>
//                 Jordan Mele <https://github.com/Silic0nS0ldier>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
// TypeScript Version: 4.1

// Based on https://stackoverflow.com/a/49683575/4728587

type OptionalPropertyNames<T> =
  { [K in keyof T]-?: ({} extends { [P in K]: T[K] } ? K : never) }[keyof T];

type SpreadProperties<L, R, K extends keyof L & keyof R> =
  { [P in K]: L[P] | Exclude<R[P], undefined> };

type Id<T> = T extends infer U ? { [K in keyof U]: U[K] } : never

type SpreadTwo<L, R> = Id<
  & Pick<L, Exclude<keyof L, keyof R>>
  & Pick<R, Exclude<keyof R, OptionalPropertyNames<R>>>
  & Pick<R, Exclude<OptionalPropertyNames<R>, keyof L>>
  & SpreadProperties<L, R, OptionalPropertyNames<R> & keyof L>
>;

type Filter1<T> = T extends object ? T : {};
type Filter2<T> = T extends any[] ? {} : T;

type Filter<T> = Filter2<Filter1<T>>;

type Spread<A extends readonly [...any]> = A extends [infer L, ...infer R] ?
  SpreadTwo<Filter<L>, Spread<R>> : unknown

// caps out at 8 params, 9th results in TS bailout
declare function extend<A extends any[]>(...a: [...A]): Spread<A>;

// deep not implemented

export = extend;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant