Greg Ruhnow
Greg Ruhnow

Reputation: 303

Typescript error on valid javascript

I'm trying to do the following in typescript:

var testHier = [
    { content:"1", opened:true, children: [
        { content:"1.1" }
    ]},
    { content: "2", opened:true, children: [
        { content:"2.1", opened:false, children: [
            { content:"2.1.1", value:"2.1.1" }
        ]},
        { content: "2.2", value: "2.2" }
    ]}
]

but when I compile I get the error:

"Incompatible types in array literal expression: Type '{ content: string; opened: bool; children: { content: string; value: string; }[]; }' is missing property 'value' from type '{ content: string; value: string; }'"

If I change

{ content:"2.1", opened:false, children: [

to

{ content:"2.1", opened:false, value:"foo", children: [

the error goes away.

I tested the declaration in the chrome console and it seems to work just fine. Since this is just javascript I'd expect it to get passes straight through, but that doesn't seem to be the case. Anyone know what's going on here?

Upvotes: 2

Views: 3080

Answers (1)

Fenton
Fenton

Reputation: 251222

You just need to help it out with a bit of type information:

interface IExample {
    content: string;
    opened?: bool;
    value?: string;
    children?: IExample[];
}

var testHier: IExample[] = [
{ 
    content:"1", 
    opened:true, 
    children: [
        { 
            content:"1.1" 
        }
    ]
},
{
    content: "2", 
    opened:true, 
    children: [
        { 
            content:"2.1", 
            opened:false, 
            children: [
                { 
                    content:"2.1.1", 
                    value:"2.1.1"
                }
            ]
        },
        { 
            content: "2.2", 
            value: "2.2" 
        }
    ]
}];

It is trying to work out what the types are in each part of the array and can't come up with the required commonality to guess - in an array it needs everything to be the same type (i.e. all strings, or all numbers, but not a mixture!). The IExample interface helps by specifying the any type.

Why has TypeScript done this?

TypeScript wants to help you. If it can infer a type for you, to save you having to explicitly declare it, it will. On the whole this is beneficial - it would detect the error in the following script:

var x = [
    10,
    20,
    "30",
    50
];

In this case, it infers you have an array of numbers as warns you that there is a string in there. If it used any instead of cleverly working out the types, you wouldn't get this kind of assistance.

You can still decide that you want to have a mixed array by telling TypeScript that x is of type any[] in which case the error goes away.

It is better that TypeScript starts by warning you about incompatible types in case you made a mistake - for example in your case you might have forgotten to add opened and value to each of the objects - so TypeScript could have saved you from an error.

Upvotes: 5

Related Questions