代码之家  ›  专栏  ›  技术社区  ›  Neonit Humam Helfawi

Typescript中接口和交集类型的错误推断(严格模式)

  •  0
  • Neonit Humam Helfawi  · 技术社区  · 6 年前

    我在Typescript中遇到了一个奇怪的接口和交集类型行为 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; }'.
    

    对备选方案的评论:

    • [A] Breaker 也谁知道这会是真的 打破 我的代码?)
    • [B] 这会使你离开 limit 这是不可能的。
    • [C] 这是我现在将使用的替代方案。
    • [D] 只是[C]内联的。
    • [E]

    我的问题是: 为什么不起作用?还是这是一只虫子?或者我可以/应该以某种方式改进/纠正 断路器 / BaseOptions 打字?如果是,怎么做?


    编辑1

    我的 tsconfig.json :

    {
      "compilerOptions": {
        "target": "es2017",
        "module": "commonjs",
        "moduleResolution": "node",
        "noUnusedLocals": true,
        "strict": true,
        "experimentalDecorators": true,
        "rootDir": "./",
        "lib": [
          "ES2017"
        ],
        "types": [
          "node"
        ]
      }
    }
    
    0 回复  |  直到 6 年前