首页 > 解决方案 > Typescript 中接口和交叉类型的错误推断(严格模式)

问题描述

我在启用的 Typescript 中遇到了接口和交集类型的奇怪行为strictNullChecks。我已将我的原始代码分解为一个最小的通用(独立)片段(如果您想摆弄,请确保启用strictNullChecks),您可以在下面找到它。我还包括了一些替代行,当使用它们代替上面的行时,可以使代码段编译时没有错误。我在这个片段中得到的错误也包括在下面。

type FooOptions<OptionsT> = OptionsT & BaseOptions<OptionsT>;

interface Breaker<OptionsT>
{ (this: Foo<OptionsT>): void; }

interface BaseOptions<OptionsT>
{ breaker?: Breaker<OptionsT>; }
// {} // works! [A]

class Foo<OptionsT>
{
    public constructor(
        protected readonly options: FooOptions<OptionsT>,
    )
    {}
}

interface SpecialOptions
{ limit?: number; }
// { limit: number | undefined; } // works! [B]

interface BarFoo extends Foo<SpecialOptions> {}
type BarFooType = Foo<SpecialOptions>;

class FooFactory
{
    public bar(limit?: number):
        BarFoo
        // BarFooType // works! [C]
        // Foo<SpecialOptions> // works! [D]
    { return new Foo({limit}); } // ERROR comes from here
    // { return new Foo(<SpecialOptions>{limit}); } // works! [E]
}

收到的错误如下。我添加了换行符,因此您无需水平滚动。

Type 'Foo<{ limit: number | undefined; }>' is not assignable to type 'BarFoo'. Types of
property 'options' are incompatible. Type 'FooOptions<{ limit: number | undefined; }>' is not
assignable to type 'FooOptions<SpecialOptions>'. Type
'FooOptions<{ limit: number | undefined; }>' is not assignable to type
'BaseOptions<SpecialOptions>'. Types of property 'breaker' are incompatible. Type
'Breaker<{ limit: number | undefined; }> | undefined' is not assignable to type
'Breaker<SpecialOptions> | undefined'. Type 'Breaker<{ limit: number | undefined; }>' is not
assignable to type 'Breaker<SpecialOptions> | undefined'. Type
'Breaker<{ limit: number | undefined; }>' is not assignable to type
'Breaker<SpecialOptions>'. Type 'SpecialOptions' is not assignable to type
'{ limit: number | undefined; }'. Property 'limit' is optional in type 'SpecialOptions' but
required in type '{ limit: number | undefined; }'.

对替代品的评论:

我的问题是:为什么它不起作用?或者这是一个错误?或者我可以/应该以某种方式改进/纠正Breaker/BaseOptions打字?如果是这样,怎么做?


编辑 1

我的tsconfig.json

{
  "compilerOptions": {
    "target": "es2017",
    "module": "commonjs",
    "moduleResolution": "node",
    "noUnusedLocals": true,
    "strict": true,
    "experimentalDecorators": true,
    "rootDir": "./",
    "lib": [
      "ES2017"
    ],
    "types": [
      "node"
    ]
  }
}

标签: typescript

解决方案


推荐阅读