fix: NonEmptyObject should ignore index signatures when checking for required keys#1464
Conversation
…required keys When T has an index signature, HasRequiredKeys returns true even if no concrete keys are present. Use OmitIndexSignature to exclude index signatures before checking for required keys. Fixes sindresorhus#821
|
I don’t think this actually fixes the repro from the issue. It changes the I checked this manually with: type Arguments = NonEmptyObject<{
[argument: string]: string | number | undefined;
}>;
// @ts-expect-error
const argumentsValue: Arguments = {};
type CommonArguments = {
[filter: string]: NonEmptyObject<{
[argument: string]: string | number | undefined;
}>;
};
// @ts-expect-error
const commonArguments: CommonArguments = {
foo: {},
};TypeScript reports both |
|
I have updated the PR to address the dynamic index signature issue. Specifically:
|
…Object
Adds the exact repro cases from sindresorhus's review comment:
- NonEmptyObject<{[key: string]: V}> must resolve to never
- {} must not be assignable to NonEmptyObject<PureIndexSignature>
- {} must not be assignable to nested NonEmptyObject<PureIndexSignature>
|
I've pushed a follow-up commit that adds your exact repro cases as regression tests: // @ts-expect-error - {} must NOT be assignable to NonEmptyObject<PureIndexSignature>
const _badPure: NonEmptyObject<{[argument: string]: string | number | undefined}> = {};
// @ts-expect-error - {} must NOT be assignable to the nested form
const _badNested: {[filter: string]: NonEmptyObject<{[argument: string]: string | number | undefined}>} = {foo: {}};Both |
|
Thanks for iterating on this — the updated approach reads much better. I checked out the branch: A few things I noticed while testing:
|
When
Thas an index signature like[filter: string]: SomeType,HasRequiredKeys<T>returnstruebecause it counts the index signature as a required key. This causesNonEmptyObjectto pass through the type as-is even when no concrete keys are present.Using
OmitIndexSignature<T>before checking for required keys ensures index signatures are excluded from the check.Before:
After: The above correctly fails type checking.
Fixes #821
PayPal: n6085530@gmail.com