How do you define an array of Partials in TypeScript?

Viewed 5585

For instance,

type User = {
  first_name: string,
  last_name: string,
  notes: string
}

Which of the following would work?

const users:Partial<User>[] = [{first_name: "Name"}]; // A

const users:Partial<User[]> = [{first_name: "Name"}]; // B

const users:[Partial<User>] = [{first_name: "Name"}]; // C

Weirdly, all of these appear to be valid TypeScript at compile time.

Thanks in advance.

3 Answers

The proper way is

const users:Partial<User>[] = [{first_name: "Name"}];

Partial<User[]> means that it has some of Array properties.

[Partial<User>] means that it's an array of partial User with 1 element.

Weirdly, all of these appear to be valid TypeScript at compile time

The syntax is valid but types aren't. It's expected that Partial<User[]> causes an error because types are incompatible.

Option A gives you an array containing Partials:

const users:Partial<User>[] = [{first_name: "Name"}]; // A

If it helps you understand, think about how you would define an array of Partials if the type weren't generic. That would be Partial[].

If you remove the generic type from option B, you'd get a single Partial instead of an array.

Option C is a tuple rather than an array.

Even though all turn out to be similar in complied JavaScript, there is huge difference in all three.

const users:Partial<User>[] = [{first_name: "Name"}];

This is a valid array of Partial. By appending [] at end, you are specifying that the length is unknown and can be any. So you can have as many elements of User in this array as you want. Remember this as it will help with next example.

In the second example, you are trying to do the same but it is different and invalid.

const users:Partial<User[]> = [{first_name: "Name"}];

You are trying to turn an array of User to Partial. So, User is not yet partial but you are trying to turn array into partial. You get an error:

Type '{ first_name: string; }[]' is not assignable to type 'Partial<User[]>'.
  Types of property 'pop' are incompatible.
    Type '() => { first_name: string; }' is not assignable to type '() => User'.
      Type '{ first_name: string; }' is not assignable to type 'User'.
        Property 'last_name' is missing in type '{ first_name: string; }'.

In your 3rd example:

const users: [Partial<User>] = [{ first_name: "Name" }]; // C

You are doing the same as in your first example and it is valid. Creating an array of Partial but there is a difference. Here, you can have only one element in this array. If you try to add another element, you get an error because with [Partial<User>] also specifies that the length of array will be exactly 1.

Let us see, what is the error in following:

const users: [Partial<User>] =    [{ first_name: "Name" }, { first_name: "Name" }];

Here the error is:

    Type '[{ first_name: string; }, { first_name: string; }]' is not assignable to type '[Partial<User>]'.
  Types of property 'length' are incompatible.
    Type '2' is not assignable to type '1'.

Strangely, the TypeScript does compile all of your examples to similar array, but it does give you the errors in its online compiler.

There is an online tool of TypeScript to play and see your code turning into JavaScript. https://www.typescriptlang.org/play/ The good thing is that you can actually see the problem with your code in the typescript code section. Any issue with code will have a red underline and hover over it to see the details.

TypeScript Online Play displaying error

Related