Skip to content

Fix TS errors #1580

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/unlucky-pumpkins-march.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"openapi-fetch": patch
---

Fix type errors
2 changes: 1 addition & 1 deletion packages/openapi-fetch/examples/nextjs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"react-dom": "18.2.0"
},
"devDependencies": {
"@types/node": "20.11.19",
"@types/node": "20.11.24",
"@types/react": "18.2.20",
"@types/react-dom": "18.2.7",
"openapi-typescript": "workspace:^",
Expand Down
2 changes: 1 addition & 1 deletion packages/openapi-fetch/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
"openapi-typescript-fetch": "^1.1.3",
"superagent": "^8.1.2",
"typescript": "^5.3.3",
"vitest": "^1.2.2",
"vitest": "^1.3.1",
"vitest-fetch-mock": "^0.2.2"
}
}
31 changes: 19 additions & 12 deletions packages/openapi-fetch/src/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import type {
ErrorResponse,
SuccessResponse,
FilterKeys,
HasRequiredKeys,
HttpMethod,
MediaType,
OperationRequestBodyContent,
PathsWithMethod,
ResponseObjectMap,
OperationRequestBodyContent,
HasRequiredKeys,
SuccessResponse,
} from "openapi-typescript-helpers";

// Note: though "any" is considered bad practice in general, this library relies
Expand Down Expand Up @@ -80,7 +81,7 @@ type BodyType<T = unknown> = {
stream: Response["body"];
};
export type ParseAs = keyof BodyType;
export type ParseAsResponse<T, O extends FetchOptions> = O extends {
export type ParseAsResponse<T, O> = O extends {
parseAs: ParseAs;
}
? BodyType<T>[O["parseAs"]]
Expand Down Expand Up @@ -110,13 +111,7 @@ export type RequestBodyOption<T> =
export type FetchOptions<T> = RequestOptions<T> &
Omit<RequestInit, "body" | "headers">;

/** This type helper makes the 2nd function param required if params/requestBody are required; otherwise, optional */
export type MaybeOptionalInit<P extends {}, M extends keyof P> =
HasRequiredKeys<FetchOptions<FilterKeys<P, M>>> extends never
? [(FetchOptions<FilterKeys<P, M>> | undefined)?]
: [FetchOptions<FilterKeys<P, M>>];

export type FetchResponse<T, O extends FetchOptions> =
export type FetchResponse<T, O> =
| {
data: ParseAsResponse<
FilterKeys<SuccessResponse<ResponseObjectMap<T>>, MediaType>,
Expand Down Expand Up @@ -174,7 +169,19 @@ export interface Middleware {
onResponse?: typeof onResponse;
}

export type ClientMethod<Paths extends {}, M> = <
/** This type helper makes the 2nd function param required if params/requestBody are required; otherwise, optional */
export type MaybeOptionalInit<
P extends Record<HttpMethod, {}>,
M extends keyof P,
> =
HasRequiredKeys<FetchOptions<FilterKeys<P, M>>> extends never
? [(FetchOptions<FilterKeys<P, M>> | undefined)?]
: [FetchOptions<FilterKeys<P, M>>];

export type ClientMethod<
Paths extends Record<string, Record<HttpMethod, {}>>,
M extends HttpMethod,
> = <
P extends PathsWithMethod<Paths, M>,
I extends MaybeOptionalInit<Paths[P], M>,
>(
Expand Down
1 change: 0 additions & 1 deletion packages/openapi-fetch/test/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
// @ts-expect-error
import createFetchMock from "vitest-fetch-mock";
import createClient, {
Expand Down
1 change: 0 additions & 1 deletion packages/openapi-fetch/test/v7-beta.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { afterEach, beforeAll, describe, expect, it, vi } from "vitest";
// @ts-expect-error
import createFetchMock from "vitest-fetch-mock";
import createClient, {
Expand Down
4 changes: 2 additions & 2 deletions packages/openapi-fetch/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@
"moduleResolution": "NodeNext",
"noUncheckedIndexedAccess": true,
"outDir": "dist",
"skipLibCheck": true,
"skipLibCheck": false,
"strict": true,
"target": "ESNext",
"types": ["vitest/globals"]
},
"include": ["src", "test"],
"exclude": ["node_modules"]
"exclude": ["examples", "node_modules"]
}
18 changes: 10 additions & 8 deletions packages/openapi-typescript-helpers/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,14 +58,15 @@ export type OperationRequestBodyMediaContent<T> =
? FilterKeys<NonNullable<OperationRequestBody<T>>, "content"> | undefined
: FilterKeys<OperationRequestBody<T>, "content">;
/** Return first `content` from a Request Object Mapping, allowing any media type */
export type OperationRequestBodyContent<T> = FilterKeys<
OperationRequestBodyMediaContent<T>,
MediaType
> extends never
?
| FilterKeys<NonNullable<OperationRequestBodyMediaContent<T>>, MediaType>
| undefined
: FilterKeys<OperationRequestBodyMediaContent<T>, MediaType>;
export type OperationRequestBodyContent<T> =
FilterKeys<OperationRequestBodyMediaContent<T>, MediaType> extends never
?
| FilterKeys<
NonNullable<OperationRequestBodyMediaContent<T>>,
MediaType
>
| undefined
: FilterKeys<OperationRequestBodyMediaContent<T>, MediaType>;
/** Return first 2XX response from a Response Object Map */
export type SuccessResponse<T> = ResponseContent<FilterKeys<T, OkStatus>>;
/** Return first 5XX or 4XX response (in that order) from a Response Object Map */
Expand Down Expand Up @@ -97,4 +98,5 @@ export type FindRequiredKeys<T, K extends keyof T> = K extends unknown
? never
: K
: K;
/** Does this object contain required keys? */
export type HasRequiredKeys<T> = FindRequiredKeys<T, keyof T>;
10 changes: 5 additions & 5 deletions packages/openapi-typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,21 +62,21 @@
"typescript": "^5.x"
},
"dependencies": {
"@redocly/openapi-core": "^1.9.0",
"@redocly/openapi-core": "^1.10.3",
"ansi-colors": "^4.1.3",
"supports-color": "^9.4.0",
"yargs-parser": "^21.1.1"
},
"devDependencies": {
"@types/degit": "^2.8.6",
"@types/js-yaml": "^4.0.9",
"@types/node": "^20.11.19",
"@types/node": "^20.11.24",
"degit": "^2.8.4",
"del-cli": "^5.1.0",
"esbuild": "^0.20.0",
"esbuild": "^0.20.1",
"execa": "^7.2.0",
"typescript": "^5.3.3",
"vite-node": "^1.2.2",
"vitest": "^1.2.2"
"vite-node": "^1.3.1",
"vitest": "^1.3.1"
}
}
3 changes: 2 additions & 1 deletion packages/openapi-typescript/test/index.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { fileURLToPath } from "node:url";
import { beforeAll, describe, expect, test, vi } from "vitest";
import openapiTS, { astToString } from "../src/index.js";
import type { OpenAPI3, OpenAPITSOptions } from "../src/types.js";
import type { TestCase } from "./test-helpers.js";
Expand Down Expand Up @@ -692,7 +693,7 @@ export type operations = Record<string, never>;`,
);
}

it("does not mutate original reference", async () => {
test("does not mutate original reference", async () => {
const schema: OpenAPI3 = {
openapi: "3.1",
info: { title: "test", version: "1.0" },
Expand Down
56 changes: 28 additions & 28 deletions packages/openapi-typescript/test/lib/ts.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
} from "../../src/lib/ts.js";

describe("addJSDocComment", () => {
it("single-line comment", () => {
test("single-line comment", () => {
const property = ts.factory.createPropertySignature(
undefined,
"comment",
Expand All @@ -30,7 +30,7 @@ describe("addJSDocComment", () => {
}`);
});

it("multi-line comment", () => {
test("multi-line comment", () => {
const property = ts.factory.createPropertySignature(
undefined,
"comment",
Expand All @@ -57,7 +57,7 @@ describe("addJSDocComment", () => {
}`);
});

it("escapes internal comments", () => {
test("escapes internal comments", () => {
const property = ts.factory.createPropertySignature(
undefined,
"comment",
Expand All @@ -77,19 +77,19 @@ describe("addJSDocComment", () => {
});

describe("oapiRef", () => {
it("single part", () => {
test("single part", () => {
expect(astToString(oapiRef("#/components")).trim()).toBe(`components`);
});

it("multiple parts", () => {
test("multiple parts", () => {
expect(astToString(oapiRef("#/components/schemas/User")).trim()).toBe(
`components["schemas"]["User"]`,
);
});
});

describe("tsEnum", () => {
it("string members", () => {
test("string members", () => {
expect(astToString(tsEnum("-my-color-", ["green", "red", "blue"])).trim())
.toBe(`enum MyColor {
green = "green",
Expand All @@ -98,7 +98,7 @@ describe("tsEnum", () => {
}`);
});

it("name from path", () => {
test("name from path", () => {
expect(
astToString(
tsEnum("#/paths/url/get/parameters/query/status", [
Expand All @@ -112,7 +112,7 @@ describe("tsEnum", () => {
}`);
});

it("string members with numeric prefix", () => {
test("string members with numeric prefix", () => {
expect(astToString(tsEnum("/my/enum/", ["0a", "1b", "2c"])).trim())
.toBe(`enum MyEnum {
Value0a = "0a",
Expand All @@ -121,7 +121,7 @@ describe("tsEnum", () => {
}`);
});

it("number members", () => {
test("number members", () => {
expect(astToString(tsEnum(".Error.code.", [100, 101, 102])).trim())
.toBe(`enum ErrorCode {
Value100 = 100,
Expand All @@ -130,7 +130,7 @@ describe("tsEnum", () => {
}`);
});

it("number members with x-enum-descriptions", () => {
test("number members with x-enum-descriptions", () => {
expect(
astToString(
tsEnum(
Expand All @@ -153,7 +153,7 @@ describe("tsEnum", () => {
}`);
});

it("x-enum-varnames", () => {
test("x-enum-varnames", () => {
expect(
astToString(
tsEnum(
Expand All @@ -173,7 +173,7 @@ describe("tsEnum", () => {
}`);
});

it("x-enum-varnames with numeric prefix", () => {
test("x-enum-varnames with numeric prefix", () => {
expect(
astToString(
tsEnum(
Expand All @@ -189,7 +189,7 @@ describe("tsEnum", () => {
}`);
});

it("partial x-enum-varnames and x-enum-descriptions", () => {
test("partial x-enum-varnames and x-enum-descriptions", () => {
expect(
astToString(
tsEnum(
Expand All @@ -209,7 +209,7 @@ describe("tsEnum", () => {
}`);
});

it("x-enum-descriptions with x-enum-varnames", () => {
test("x-enum-descriptions with x-enum-varnames", () => {
expect(
astToString(
tsEnum(
Expand Down Expand Up @@ -237,15 +237,15 @@ describe("tsEnum", () => {
});

describe("tsPropertyIndex", () => {
it("numbers -> number literals", () => {
test("numbers -> number literals", () => {
expect(astToString(tsPropertyIndex(200)).trim()).toBe(`200`);
expect(astToString(tsPropertyIndex(200.5)).trim()).toBe(`200.5`);
expect(astToString(tsPropertyIndex(Infinity)).trim()).toBe(`Infinity`);
expect(astToString(tsPropertyIndex(NaN)).trim()).toBe(`NaN`);
expect(astToString(tsPropertyIndex(10e3)).trim()).toBe(`10000`);
});

it("valid strings -> identifiers", () => {
test("valid strings -> identifiers", () => {
expect(astToString(tsPropertyIndex("identifier")).trim()).toBe(
`identifier`,
);
Expand All @@ -257,7 +257,7 @@ describe("tsPropertyIndex", () => {
expect(astToString(tsPropertyIndex("10e3")).trim()).toBe(`"10e3"`);
});

it("invalid strings -> string literals", () => {
test("invalid strings -> string literals", () => {
expect(astToString(tsPropertyIndex("kebab-case")).trim()).toBe(
`"kebab-case"`,
);
Expand All @@ -273,27 +273,27 @@ describe("tsPropertyIndex", () => {
});

describe("tsIsPrimitive", () => {
it("null", () => {
test("null", () => {
expect(tsIsPrimitive(NULL)).toBe(true);
});

it("number", () => {
test("number", () => {
expect(tsIsPrimitive(NUMBER)).toBe(true);
});

it("string", () => {
test("string", () => {
expect(tsIsPrimitive(STRING)).toBe(true);
});

it("boolean", () => {
test("boolean", () => {
expect(tsIsPrimitive(BOOLEAN)).toBe(true);
});

it("array", () => {
test("array", () => {
expect(tsIsPrimitive(ts.factory.createArrayTypeNode(STRING))).toBe(false);
});

it("object", () => {
test("object", () => {
expect(
tsIsPrimitive(
ts.factory.createTypeLiteralNode([
Expand All @@ -310,29 +310,29 @@ describe("tsIsPrimitive", () => {
});

describe("tsUnion", () => {
it("none", () => {
test("none", () => {
expect(astToString(tsUnion([])).trim()).toBe(`never`);
});

it("one", () => {
test("one", () => {
expect(astToString(tsUnion([STRING])).trim()).toBe(`string`);
});

it("multiple (primitive)", () => {
test("multiple (primitive)", () => {
expect(
astToString(tsUnion([STRING, STRING, NUMBER, NULL, NUMBER, NULL])).trim(),
).toBe(`string | number | null`);
});

it("multiple (const)", () => {
test("multiple (const)", () => {
expect(
astToString(
tsUnion([NULL, tsLiteral("red"), tsLiteral(42), tsLiteral(false)]),
).trim(),
).toBe(`null | "red" | 42 | false`);
});

it("multiple (object types)", () => {
test("multiple (object types)", () => {
const obj = ts.factory.createTypeLiteralNode([
ts.factory.createPropertySignature(undefined, "foo", undefined, STRING),
]);
Expand Down
Loading