Reputation: 167
I have a type:
type MyObject = {
[index:string]: MyObject | Function | "wtf"
}
When I create a variable of this type, it compiles in this basic example:
// compiles
const myObj: MyObject = {
name: "wtf",
};
As well as with a nested key - note the nested key is notName:
, instead of name:
// compiles
const myObj: MyObject = {
wrapper: {
notName: "wtf",
},
};
As soon as I change the nested key to name:
, it fails to compile:
/*
Type '{ name: string; }' is not assignable to type 'Function | MyObject | "wtf"'.
Type '{ name: string; }' is not assignable to type '"wtf"'
*/
const myObj: MyObject = {
wrapper: {
name: "wtf",
},
};
Other weirdness, if I remove Function
from the union, it compiles:
type MyObjectNoFunction = {
[index:string]: MyObjectNoFunction | "wtf"
}
let myObjNoFn: MyObjectNoFunction = {
wrapper: {
name: "wtf"
}
};
Even more weirdness, if I don't include any libs, like es6, in my tsconfig, everything compiles.
tsconfig:
{
"compilerOptions": {
"lib": [
"es6"
],
"noImplicitReturns": true,
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": true,
"strict": true
}
}
Check out a full example on github
Upvotes: 1
Views: 65
Reputation: 10823
Not sure exactly what's causing TS to get confused, but here's a wild guess: Maybe this is because Function
has a name
property in es6, so TypeScript infers that { name: "something" }
is an unfinished Function
type declaration.
In any case, here are a few ways to fix it.
You can explicitly type the inner object, like this:
type MyObject = {
[index:string]: MyObject | Function | "wtf"
}
const innerMyObject: MyObject = {
name: "wtf",
}
const myObj: MyObject = {
wrapper: innerMyObject,
};
Or you can explicitly type the string literal, like this:
type MyObject = {
[index:string]: MyObject | Function | "wtf"
}
const myObj: MyObject = {
wrapper: {
name: "wtf" as "wtf",
},
};
Upvotes: 4