Closed RPGillespie6 closed 3 weeks ago
I think the problem is here:
export type FindRequiredKeys<T, K extends keyof T> = K extends unknown ? (undefined extends T[K] ? never : K) : K;
/** Does this object contain required keys? */
export type HasRequiredKeys<T> = FindRequiredKeys<T, keyof T>;
A couple problems:
K extends unknown
seems to always be true (how can K extends unknown
ever be false?)undefined extends T[K]
seems to always be false (how can undefined extends T[K]
ever be true?)If I change it to this:
export type FindRequiredKeys<T, K extends keyof T> = never extends T[K] ? never : K;
/** Does this object contain required keys? */
export type HasRequiredKeys<T> = FindRequiredKeys<T, keyof T>;
It fixes it, but I'm not sure if that causes any regressions.
I tracked this down to behavioral differences based on the strictNullChecks
(or strict
, which includes strictNullChecks
) compiler option. When that option is false
(the default), undefined
is considered to be a subtype of every other type except never
. In that case, given this definition:
type Parameters = {
query?: {
name?: string;
status?: string;
};
header?: never;
path: {
petId: number;
};
cookie?: never;
};
HasRequiredKeys<Parameters>
will resolve to "header" | "cookie"
, which is clearly not the intent of that helper type. However, with strictNullChecks
enabled, it correctly resolves to "path"
.
The problem is most noticeable in the case mentioned in the original issue, when no parameters are defined:
type Parameters = {
query?: never;
header?: never;
path?: never;
cookie?: never;
};
HasRequiredKeys<Parameters>
resolves to "query" | "header" | "path" | "cookie"
, which then makes params
a required property in the request init object.
I think we could fix this by replacing HasRequiredKeys
with a helper type that doesn't rely on the inconsistent behavior of undefined extends T
. I'm working on a PR that uses this helper instead:
type RequiredKeysOf<T> = {
[K in keyof T]: {} extends Pick<T, K> ? never : K;
}[keyof T];
The following snippet of code should be valid, as per the README:
However, it is failing with:
If I change it to:
the error goes away.
Is this a recent regression? I don't remember it doing this before. I'm using typescript
5.5.4
, openapi-fetch0.10.2
, and openapi-typscript7.1.0
.my
tsconfig.json
:Checklist