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

Proposal Inferred Partial type #463

Open
Hideman85 opened this issue Sep 9, 2022 · 2 comments
Open

Proposal Inferred Partial type #463

Hideman85 opened this issue Sep 9, 2022 · 2 comments

Comments

@Hideman85
Copy link

Hideman85 commented Sep 9, 2022

I have really no idea how to call this helper, but let me describe the use case.

// Lets imagine I have an options type
type Options {
  readOnly?: boolean;
  required?: boolean;
  filters?: Record<string, string>;
  // ...
}

// Now lets see how I can use in a function
const buildOptions(required: boolean, name: string, team?: string) => {
  const options: Options = {
     required,
     filters: {
       name,
     },
   };
   
   if (team) {
     // Issue is that filters even if defined above remains optional/partial
     options.filters.team = team;
   }
}

// Today we could manuall build the correct type as
const options: Options & Pick<Required<NonNullable<Options>>, 'required' | 'filters'> = {...}

// Issue is when adding more property you always need to add the property in the list
// I tried the following without success to infer the type without explicitely giving the keys
export const makeInferredPartial = <Base, Real extends Required<NonNullable<Base>>>(
  // partial: {[Key in keyof Base]: Required<NonNullable<Base>>[Key]} extends infer Return ? Partial<Base> & Return : never,
  partial: Real,
) => partial;

const options = makeInferredPartial<Options>({
  filters: { name: 'Hello world' },
})
// Would expect the type to be like
{
  readOnly?: boolean;
  required?: boolean;
  filters: Record<string, string>; // Note it become defined
  // ...
}
// Then the following works
options.filters.team = 'admin';

Please let me know if that make sense and if you could help me to build this helper. I think this become pretty useful when the type has plenty of props and you just want to define them and infer the correct typing.

Thanks in advance for your help.

Upvote & Fund

  • We're using Polar.sh so you can upvote and help fund this issue.
  • The funding will be given to active contributors.
  • Thank you in advance for helping prioritize & fund our backlog.
Fund with Polar
@papb
Copy link
Contributor

papb commented Sep 20, 2022

Can't you just let options be typed automatically, and enforce the return type of your buildOptions function instead?

function buildOptions(required: boolean, name: string, team?: string): Options {
  const options = {
     required,
     filters: {
       name,
     },
   };
   
   if (team) {
     options.filters.team = team;
   }

   return options;
}

@Hideman85
Copy link
Author

In this way you do not get the other properties neither the real type of them 'foo' | 'bar' !== string.

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

2 participants