67

I have my interface like this

export interface Details {
  Name: [{
    First: string;
    Last: string;
  }];
}   

I have an observable config variable:

Configuration: KnockoutObservable<Details> = ko.observable<Details>();

and I would like to assign it a value in the constructor as follows:

config = {
  Name: [{
    First: "ABC",
    Last: "DEF"
  },
  {
    First: "LMN",
    Last: "XYZ"
  }]
};

this.Configuration(config);

and I am getting an error:

Types of property 'Name' is incompatible and property '0' is missing in type.
Type '{ First:string; Last:string; }[]' is not assignable to 
type '[{ First: string; Last:string; }]'

I don't have control on changing the interface as it is being used elsewhere.
What is the correct way to initialize this config variable ?

Thanks in advance.

4 Answers 4

86

I came across the same issue and got around it by changing the interface to:

    interface Details {
        Name: {
            First: string;
            Last: string;
        }[];
    }

I know you may not want the interface changed but hope this helps for anyone that is in this situation.

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

4 Comments

I want to kiss you! I fought this for so long without any answers. Thanks you so much!
Ha! I am glad this helped because I definitely found myself in the same boat some time ago.
Just in case it isn't obvious the solution here is to move the [] to immediately follow {} instead of being [ { } ]. This is a change in syntax with recent typescript version.
No problem! Glad to see this is still helping people years down the line!
68

This error can come from incorrectly typing an array (like I just did):

myArray:[]; //Incorrect, results in error message of `Property '0' is missing in type`

myArray: Array<string>; //Correct

myArray: string[]; //Also correct

The reason is that brackets denote a tuple in Typescript, not an array.

The Docs

1 Comment

brackets? braces? what you mention for me are brackets [] braces are for me{} at best the terms are overloaded. And honestly, why the heck would TS use [] to denote a tuple? that's just wayyyy beyond me.
16

In this type definition:

interface Details {
  Name: [{
    First: string;
    Last: string;
  }];
}

Name is not an array at compile-time. It's a tuple with one element. Tuples in Typescript are allowed to have extra elements, but they can't have missing elements. As a 1-tuple, Name is essentially an array which must have at least one element.

However, in this value:

const config = {
  Name: [{
    First: "ABC",
    Last: "DEF"
  },
  {
    First: "LMN",
    Last: "XYZ"
  }]
};

Since there is no explicit typing, the Name property here defaults to array type. Arrays can have any number of elements, including zero - which doesn't fit in a 1-tuple. Hence your error.

Your error can be fixed by giving the compiler a hint that your literal is actually a tuple:

const config: Details = { Name: [{...}, {...}] };

If you do need to be able to take in an array of names, you'll have to do some casting, maybe something like this:

if (names.length > 0) {
  const config = {
    Name: names as Details['Name']
  };
  Configuration(config);
}

(You could remove the if check if you can determine that the tuple was simply a mistake by whoever wrote the typings.)

Tuples reference: https://www.typescriptlang.org/docs/handbook/basic-types.html

1 Comment

great answer! just helped me out.
11

Updating the interface to following should fix the issue :

 interface Details {
        Name: Array<{
            First: string;
            Last: string;
        }>;
    }

2 Comments

Can you explain why this fixes the issue please?
I believe, [] in typescript refers to tuple type , Array<> is a closer representation of javascript arrays. That's my understanding .

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.