Skip to content

Commit 444a49a

Browse files
committed
feat(typescript): add topType option allowing to choose any over unknown
1 parent 4949a34 commit 444a49a

File tree

8 files changed

+66
-6
lines changed

8 files changed

+66
-6
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@hey-api/openapi-ts': patch
3+
---
4+
5+
feat(typescript): add `topType` option allowing to choose `any` over `unknown`

packages/openapi-ts-tests/main/test/3.1.x.test.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,20 @@ describe(`OpenAPI ${version}`, () => {
7070
input: 'additional-properties-true.json',
7171
output: 'additional-properties-true',
7272
}),
73-
description: 'allows arbitrary properties on objects',
73+
description: 'allows arbitrary properties on objects (unknown top type)',
74+
},
75+
{
76+
config: createConfig({
77+
input: 'additional-properties-true.json',
78+
output: 'additional-properties-true-any',
79+
plugins: [
80+
{
81+
name: '@hey-api/typescript',
82+
topType: 'any',
83+
},
84+
],
85+
}),
86+
description: 'allows arbitrary properties on objects (any top type)',
7487
},
7588
{
7689
config: createConfig({
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// This file is auto-generated by @hey-api/openapi-ts
2+
3+
export * from './types.gen';
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// This file is auto-generated by @hey-api/openapi-ts
2+
3+
export type Foo = {
4+
foo: string;
5+
[key: string]: any | string;
6+
};
7+
8+
export type Bar = Foo & {
9+
[key: string]: any;
10+
};
11+
12+
export type Baz = Foo & {
13+
bar: string;
14+
[key: string]: any | string;
15+
};
16+
17+
export type Qux = {
18+
[key: string]: any;
19+
};
20+
21+
export type ClientOptions = {
22+
baseUrl: `${string}://${string}` | (string & {});
23+
};

packages/openapi-ts-tests/main/test/openapi-ts.config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ export default defineConfig(() => {
169169
// name: '我_responses_{{name}}',
170170
// response: '他_response_{{name}}',
171171
// },
172+
topType: 'any',
172173
// tree: true,
173174
// webhooks: {
174175
// name: 'Webby{{name}}Hook',

packages/openapi-ts/src/plugins/@hey-api/typescript/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export const defaultConfig: HeyApiTypeScriptPlugin['Config'] = {
1212
case: 'PascalCase',
1313
exportFromIndex: true,
1414
style: 'preserve',
15+
topType: 'unknown',
1516
tree: false,
1617
},
1718
handler,

packages/openapi-ts/src/plugins/@hey-api/typescript/plugin.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,7 @@ const arrayTypeToIdentifier = ({
3939
}): ts.TypeNode => {
4040
if (!schema.items) {
4141
return tsc.typeArrayNode(
42-
tsc.keywordTypeNode({
43-
keyword: 'unknown',
44-
}),
42+
tsc.keywordTypeNode({ keyword: plugin.config.topType }),
4543
);
4644
}
4745

@@ -332,7 +330,7 @@ const tupleTypeToIdentifier = ({
332330
if (schema.const && Array.isArray(schema.const)) {
333331
itemTypes = schema.const.map((value) => {
334332
const expression = tsc.valueToExpression({ value });
335-
return expression ?? tsc.identifier({ text: 'unknown' });
333+
return expression ?? tsc.identifier({ text: plugin.config.topType });
336334
});
337335
} else if (schema.items) {
338336
for (const item of schema.items) {
@@ -432,7 +430,7 @@ const schemaTypeToIdentifier = ({
432430
});
433431
case 'unknown':
434432
return tsc.keywordTypeNode({
435-
keyword: 'unknown',
433+
keyword: plugin.config.topType,
436434
});
437435
case 'void':
438436
return tsc.keywordTypeNode({

packages/openapi-ts/src/plugins/@hey-api/typescript/types.d.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,16 @@ export type UserConfig = Plugin.Name<'@hey-api/typescript'> & {
199199
*/
200200
response?: StringName;
201201
};
202+
/**
203+
* The top type to use for untyped or unspecified schema values.
204+
*
205+
* Can be:
206+
* - `unknown` (default): safe top type, you must narrow before use
207+
* - `any`: disables type checking, can be used anywhere
208+
*
209+
* @default 'unknown'
210+
*/
211+
topType?: 'any' | 'unknown';
202212
/**
203213
* Configuration for webhook-specific types.
204214
*
@@ -429,6 +439,12 @@ export type Config = Plugin.Name<'@hey-api/typescript'> & {
429439
*/
430440
response: StringName;
431441
};
442+
/**
443+
* The top type to use for untyped or unspecified schema values.
444+
*
445+
* @default 'unknown'
446+
*/
447+
topType: 'any' | 'unknown';
432448
/**
433449
* Configuration for webhook-specific types.
434450
*

0 commit comments

Comments
 (0)