Skip to content

Commit

Permalink
Avoid adding undefined to the index signature for additionalProperties
Browse files Browse the repository at this point in the history
  • Loading branch information
Piet van Agtmaal committed Aug 11, 2023
1 parent 6899a51 commit 9169509
Show file tree
Hide file tree
Showing 9 changed files with 621 additions and 571 deletions.
5 changes: 5 additions & 0 deletions .changeset/ninety-tips-sip.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"openapi-typescript": minor
---

Avoid adding a undefined union to additionProperties
4 changes: 4 additions & 0 deletions docs/src/content/docs/advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,10 @@ However, APIs are language-agnostic, and may contain a different syntax style fr
Instead, treat “consistency” in a more holistic sense, recognizing that preserving the API schema as-written is better than adhering to language-specific style conventions.
### Enable `noUncheckedIndexAccess` in your tsconfig.json
openapi-typescript generates a `Record` for `additionalProperties` and tries to avoid adding a `undefined` union to the index signature. However, this may result in unsafe property access in TypeScript, **unless** the compiler flag `noUncheckedIndexAccess` is set. If set, TypeScript will error when you try to access a property that might not be set.
### Be specific in your schema
openapi-typescript will **never produce an `any` type**. Anything not explicated in your schema may as well not exist. For that reason, always be as specific as possible. Here’s how to get the most out of `additionalProperties`:
Expand Down
2 changes: 1 addition & 1 deletion packages/openapi-typescript/examples/digital-ocean-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11958,7 +11958,7 @@ export interface external {
* }
*/
metric: {
[key: string]: string | undefined;
[key: string]: string;
};
/**
* @example [
Expand Down
62 changes: 31 additions & 31 deletions packages/openapi-typescript/examples/github-api-next.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12220,7 +12220,7 @@ export interface components {
language?: string;
raw_url?: string;
size?: number;
} | undefined;
};
};
public: boolean;
/** Format: date-time */
Expand Down Expand Up @@ -12360,7 +12360,7 @@ export interface components {
language?: string;
raw_url?: string;
size?: number;
} | undefined;
};
};
public: boolean;
/** Format: date-time */
Expand All @@ -12386,15 +12386,15 @@ export interface components {
git_push_url?: string;
html_url?: string;
files?: {
[key: string]: ({
[key: string]: {
filename?: string;
type?: string;
language?: string;
raw_url?: string;
size?: number;
truncated?: boolean;
content?: string;
} | null) | undefined;
} | null;
};
public?: boolean;
created_at?: string;
Expand Down Expand Up @@ -13807,13 +13807,13 @@ export interface components {
/** @description Permissions requested, categorized by type of permission. */
permissions: {
organization?: {
[key: string]: string | undefined;
[key: string]: string;
};
repository?: {
[key: string]: string | undefined;
[key: string]: string;
};
other?: {
[key: string]: string | undefined;
[key: string]: string;
};
};
/** @description Date and time when the request for access was created. */
Expand Down Expand Up @@ -13843,13 +13843,13 @@ export interface components {
/** @description Permissions requested, categorized by type of permission. */
permissions: {
organization?: {
[key: string]: string | undefined;
[key: string]: string;
};
repository?: {
[key: string]: string | undefined;
[key: string]: string;
};
other?: {
[key: string]: string | undefined;
[key: string]: string;
};
};
/** @description Date and time when the fine-grained personal access token was approved to access the organization. */
Expand Down Expand Up @@ -17048,7 +17048,7 @@ export interface components {
* @description User-defined metadata to store domain-specific information limited to 8 keys with scalar values.
*/
metadata: {
[key: string]: (null | string | number | boolean) | undefined;
[key: string]: null | string | number | boolean;
};
dependency: {
/** @description Package-url (PURL) of dependency. See https://github.com/package-url/purl-spec for more details. */
Expand Down Expand Up @@ -17077,7 +17077,7 @@ export interface components {
metadata?: components["schemas"]["metadata"];
/** @description A collection of resolved package dependencies. */
resolved?: {
[key: string]: components["schemas"]["dependency"] | undefined;
[key: string]: components["schemas"]["dependency"];
};
};
/**
Expand Down Expand Up @@ -17111,7 +17111,7 @@ export interface components {
metadata?: components["schemas"]["metadata"];
/** @description A collection of package manifests, which are a collection of related dependencies declared in a file or representing a logical group of dependencies. */
manifests?: {
[key: string]: components["schemas"]["manifest"] | undefined;
[key: string]: components["schemas"]["manifest"];
};
/**
* Format: date-time
Expand Down Expand Up @@ -18250,7 +18250,7 @@ export interface components {
* @description Language
*/
language: {
[key: string]: number | undefined;
[key: string]: number;
};
/**
* License Content
Expand Down Expand Up @@ -20594,37 +20594,37 @@ export interface components {
/** @description New requested permissions, categorized by type of permission. */
permissions_added: {
organization?: {
[key: string]: string | undefined;
[key: string]: string;
};
repository?: {
[key: string]: string | undefined;
[key: string]: string;
};
other?: {
[key: string]: string | undefined;
[key: string]: string;
};
};
/** @description Requested permissions that elevate access for a previously approved request for access, categorized by type of permission. */
permissions_upgraded: {
organization?: {
[key: string]: string | undefined;
[key: string]: string;
};
repository?: {
[key: string]: string | undefined;
[key: string]: string;
};
other?: {
[key: string]: string | undefined;
[key: string]: string;
};
};
/** @description Permissions requested, categorized by type of permission. This field incorporates `permissions_added` and `permissions_upgraded`. */
permissions_result: {
organization?: {
[key: string]: string | undefined;
[key: string]: string;
};
repository?: {
[key: string]: string | undefined;
[key: string]: string;
};
other?: {
[key: string]: string | undefined;
[key: string]: string;
};
};
/**
Expand Down Expand Up @@ -37960,12 +37960,12 @@ export interface components {
};
platform?: string;
metadata?: {
[key: string]: string | undefined;
[key: string]: string;
};
repo?: string;
dependencies?: ({
[key: string]: string | undefined;
})[];
dependencies?: {
[key: string]: string;
}[];
commit_oid?: string;
};
/** package published event */
Expand Down Expand Up @@ -78906,7 +78906,7 @@ export interface operations {
200: {
content: {
"application/json": {
[key: string]: string | undefined;
[key: string]: string;
};
};
};
Expand Down Expand Up @@ -79078,7 +79078,7 @@ export interface operations {
[key: string]: {
/** @description Content of the file */
content: string;
} | undefined;
};
};
public?: boolean | ("true" | "false");
};
Expand Down Expand Up @@ -79215,12 +79215,12 @@ export interface operations {
* To delete a file, set the whole file to null. For example: `hello.py : null`.
*/
files?: {
[key: string]: (({
[key: string]: ({
/** @description The new content of the file. */
content?: string;
/** @description The new filename for the file. */
filename?: string | null;
}) | null) | undefined;
}) | null;
};
}) | null;
};
Expand Down
Loading

0 comments on commit 9169509

Please sign in to comment.