奇怪情况下的打字稿编译错误

时间:2018-08-21 19:51:16

标签: typescript

我有一个类型:

type MyObject = {
    [index:string]: MyObject | Function | "wtf"
}

当我创建这种类型的变量时,它将在以下基本示例中进行编译:

// compiles
const myObj: MyObject = {
    name: "wtf",
};

以及嵌套键-请注意,嵌套键是notName:,而不是name:

// compiles
const myObj: MyObject = {
    wrapper: {
        notName: "wtf",
    },
};

将嵌套键更改为name:后,它便无法编译:

/*
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",
    },
};

其他怪异之处,如果我从联合中删除Function,它将编译:

type MyObjectNoFunction = {
    [index:string]: MyObjectNoFunction | "wtf"
}

let myObjNoFn: MyObjectNoFunction = {
    wrapper: {
        name: "wtf"
    }
};

更奇怪的是,如果我在tsconfig中不包含任何es6之类的库,一切都会编译。

tsconfig:

{
  "compilerOptions": {
    "lib": [
      "es6"
    ],
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "noUnusedLocals": true,
    "strict": true
  }
}

签出full example on github

1 个答案:

答案 0 :(得分:4)

不确定是什么导致TS混淆,但这是一个疯狂的猜测:也许是因为Function在es6中具有name属性,因此TypeScript推断{ name: "something" }是未完成的Function类型声明。

无论如何,这里有几种修复方法。

您可以显式键入内部对象,如下所示:

type MyObject = {
  [index:string]: MyObject | Function | "wtf"
}

const innerMyObject: MyObject = {
  name: "wtf",
}

const myObj: MyObject = {
  wrapper: innerMyObject,
};

或者您可以显式键入字符串文字,例如:

type MyObject = {
  [index:string]: MyObject | Function | "wtf"
}

const myObj: MyObject = {
  wrapper: {
      name: "wtf" as "wtf",
  },
};