2

I am getting this error Expected at least 1 arguments, but got 0 or more from:

    if (initialValues.length > 0) {
      return Object.assign(...initialValues);
    }

I guess it is complaining that initialValues could be empty. However, the if condition guarantees that it won't be empty. What do I do to make typescript realize this?

2
  • 1
    Eh, this isn't exactly a duplicate of this question but it's strongly related. I had marked it as a duplicate but I'll undo that. Commented Feb 15, 2021 at 16:50
  • FYI, I've updated the answer below to show how to do this with types if you prefer. Commented Feb 15, 2021 at 17:00

1 Answer 1

6

Allowing a length check as a type guard was deemed "too complex" to be added to TypeScript (thanks @jcalz for the link!).

You can take a least three approaches:

Destructure and provide the target explicitly

Since it's not getting it from the length check, I'd probably give it the target object explicitly, like this:

const [target, ...sources] = initialValues;
if (target) {
    return Object.assign(target, ...sources);
}

It's happy with that.

Playground link

Define it as a non-empty array

This answer shows how to define a type for a non-empty array:

type NonEmptyArray<T> = [T, ...T[]];

If initialValues is known at compile-time to always have at least one element, define it using that type:

let initialValues: NonEmptyArray<YourObjectType>;

Then you can remove the if, since you know it'll always be true:

return Object.assign(...initialValues);

Use a type guard

But if it could be empty and the runtime check is needed, you can define a type guard function:

function isNotEmpty<T>(arr: T[]): arr is NonEmptyArray<T> {
    return arr.length > 0;
}

Then it's:

if (isNotEmpty(initialValues)) {
    return Object.assign(...initialValues);
}

Huge thanks to @jcalz and @VLAZ for helping with this answer.

Sign up to request clarification or add additional context in comments.

8 Comments

A curious observation - I tried a different approach using a type guard + minimum length array but the compiler throws the same error.
@VLAZ - Yeah, I tried to come at it like that too (though in a different way, [object] & object[], which doesn't work correctly anyway). Not sure why.
@VLAZ Just adding in a property whose key is 0 doesn't imply anything about the length property in TypeScript (it would be surprising if that happened for any normal object type, so it's not surprising it doesn't magically happen when one side of the intersection is an array). You could use this method for something that the compiler actually can understand
If you want to modify your answer to include that info it's fine with me. I won't add an answer myself.
In case it matters, microsoft/TypeScript#38000 is the declined request to make array.length > 0 work as a type guard.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.