Oak-Digital / types-4-strapi-2

Automate the creation of typescript interfaces for your strapi 4 projects
MIT License
24 stars 4 forks source link

Population by generic types #18

Closed Alexnortung closed 1 year ago

Alexnortung commented 1 year ago

It is possible to populate your data types through the strapi api and thus we should be able to create an interface that also populates the values to avoid extra if checks.

How it would be used:

IPage<'myRelation' | 'myRelation.image'>
// or
IPage<['myRelation', 'myRelation.image']>

This would then populate IPage with myRelation which can no longer be undefined. Also myRelation.image should also be populated, this might be more tricky, since under the hood we would need to pass only the image part to the content type of myRelation.

I think we should prioritize making this work with constant arrays, since this can be directly translated to the populate querystring in a typescript application.

Alexnortung commented 1 year ago

Here is an example of how this can be acheived

type RequiredBy<T, K extends keyof T> = Required<Pick<T, K>> & Omit<T, K>;
type ExtractNested<T, K extends string> = T extends `${K}.${infer U}` ? U : never;
type ExtractFlat<T> = T extends string ? Extract<T, 'field1' | 'field2'> : never; // Probably make this more generic.

type MyType<Populate extends string | never = never> = RequiredBy<
  {
    field1?: number;
    field2?: boolean;
    field3?: MyType<ExtractNested<Populate, 'field3'>>;
  },
  ExtractFlat<Populate>
>;

This is of course a rough sketch, but enough to get myself or someone else started.

Edit: ChatGPT also came up with a more generalized version of ExtractFlat:

type ExtractFlat<T, K extends string> = T extends string ? Extract<T, K> : T extends object ? { [P in keyof T]-?: ExtractFlat<T[P], K> } : never;
Alexnortung commented 1 year ago

This feature has been added in the newest version v0.4.0