makenotion / notion-sdk-js

Official Notion JavaScript Client
https://developers.notion.com/docs
MIT License
4.95k stars 591 forks source link

Inconsistent Typescript Type Exports #519

Open adam26davidson opened 4 months ago

adam26davidson commented 4 months ago

This is not exactly a bug but more of a request for a quality of life enhancement for typescript

I am finding that with Typescript in strict mode, it would be nice to have access to more (or maybe just all?) of the types defined in api-endpoints.d.ts, and in general, have complex types split out into exported component types.

As an example, when updating a page, I am able to build a request as follows, which is nice because I can build the request object dynamically while ensuring the request type conforms to UpdatePageParameters:

const request: UpdatePageParameters = { page_id: task.id, properties: {} };
const properties = request.properties;
if (!properties) {
  throw new Error('Properties not found');
}

properties[taskSchema.status.key] = { status: { name: taskSchema.status.options.notCompletedInTime } };
properties[taskSchema.queue.key] = { select: { name: taskSchema.queue.options.archived } };

await this.notion.pages.update(request);

First of all, I can't do this sort of thing for calls to 'pages.create()' since the type used in that request, CreatePageBodyParameters is not exported from api-endpoints.d.ts, forcing me to use any for the type of the properties object and forgo typechecking

Second of all, it would be nice to have access to an exported "UpdatePageProperties" type here so that I don't have to check that properties exists in this code - currently the definition of that object is a part of UpdatePageParameters and can't be instantiated independently (maybe there is a typescript trick i am not aware of to do this but having a type would be more ergonomic in any case)

aschleck commented 4 months ago

Agreed, it'd be amazing to have all the types exported.

In the meantime, a fun workaround. You can probably do this for input types as well.

// never call this function, it's used purely to extract the types
async function dummy(notion: NotionClient) {
  for await (
      const result of iteratePaginatedAPI(notion.databases.query, {database_id: ''})) {
    if (isFullPageOrDatabase(result)) {
      return result;
    }
  }
  throw new Error('oh no');
}

type PageObjectResponse = Awaited<ReturnType<typeof dummy>>;