kontent-ai / model-generator-js

MIT License
13 stars 9 forks source link

Support Optional Elements #39

Open itworksafisher opened 1 year ago

itworksafisher commented 1 year ago

Motivation

Currently, all content element properties are generated like they are required, i.e. that they will always have a value, yet kontent.ai allows you to mark whether a content element is required or not. Non required properties should be optional in the model.

Proposed solution

myElement: Type for required elements and myElement?: Type for optional elements.

Additional Comments

This is likely a breaking change for consumers, especially those running strict Typescript because they will now have to write code to handle checking whether optional properties have a value or not.

This could potentially be offset by adding a CLI flag for supporting optional elements so this feature is opt in.

Enngage commented 1 year ago

Hi @itworksafisher,

I would also want to support optional elements, however it's a bit more complex as this requires a refactoring on the Delivery SDK part to allow optional elements. This refactoring is all the more complicated because of preview API (where you might get non-required elements) and also the fact that the element values are wrapped in an object, so it's not just about marking entire element as optional (although it could be depending on how we choose to work with strongly typed models going forward, but I expect that the value will be within an element object).

I'm planning on looking into this in upcoming months, but I can't promise anything as of yet. I'll keep this issue open for now.

nkooman-bzs commented 1 year ago

I agree with @Enngage. It would require reworking the Delivery SDK. Type definitions for elements as a part of a content item are retrieved from the Delivery SDK package and are not generated from the library itself. Here a title element is typed as Elements.TextElement. If it is not a required field, title.value would need to be marked as optional not the title element itself.

import { type IContentItem, type Elements } from '@kontent-ai/delivery-sdk';

export type Homepage = IContentItem<{
  title: Elements.TextElement;
}>;

Perhaps we could leverage the required property defined in the generated contentTypes.ts file? However, this would move type checking to run time instead of at compile time.

itworksafisher commented 1 year ago

You could possibly do this

export type Homepage = IContentItem<{
  title: Partial<Elements.TextElement>;
}>;

But that would make both name and type of IElement<string> optional properties as well, not just value.