Open joealden opened 3 years ago
You are not passing in the required keys. See the example in https://github.com/sindresorhus/type-fest/blob/main/source/require-at-least-one.d.ts
@sindresorhus from my understanding, omitting the 2nd type argument in RequireAtLeastOne
is the same as specifying all the keys of the object passed in as the 1st type argument, so the following two types are equivalent:
type T1 = RequireAtLeastOne<{ a: string; b: string }>;
type T2 = RequireAtLeastOne<{ a: string; b: string }, "a" | "b">;
Let me know if I'm misunderstanding the usage intent for RequireAtLeastOne
, but in the example, I would expect that TS would be able to deduce (via type narrowing) that in the expression value.a ?? value.b
, if value.b
is going to be returned, because either a
or b
is required (one must exist), b
must exist (as a
didn't, as if it did, then the right hand side of the expression wouldn't be reached), which would mean that getResult
would have a return type of just string
?
I think https://github.com/sindresorhus/type-fest/commit/6110607eb99d25c7670df59d160296fcda1ac123 changed the behavior of this.
// @ulken
I ran into the same issue, even when I pass the keys as the second type parameter. I believe the RequestAtLeastOne
type's implementation just doesn't play nice with type narrowing. I'm not sure if there's an alternative implementation that would play nice in this way. For now, it seems like writing a user-defined type guard would be the best way to narrow. A less safe shortcut would be to use a non-null assertion (value.b!
).
Same thing happens with RequireExactlyOne
:
(params: RequireExactlyOne<{ a: string; b: string }>): string => {
if (params.a) return params.a;
return params.b;
~~~~~~
// Type 'string | undefined' is not assignable to type 'string'.
// Type 'undefined' is not assignable to type 'string'.ts(2322)
};
I am experiencing this same issue as well. Type does not narrow as expected in VSCode, and all keys passed as the second type parameter are treated as optional, even if I perform optional checks like shown in the examples above.
With the following example:
getResult
has a return type ofstring | undefined
, but I would expect it to have a return type ofstring
, as ifvalue.a
isundefined
,value.b
should have a type ofstring
? Would this be possible to achieve?Note that I have tested this with the latest version of
typescript
at the time of writing (4.3.5
).Upvote & Fund