typescript - 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; }'.
对替代品的评论:
[A]
没有有效的替代方案。我需要那个东西。(琐事:在我的原始代码中,它也被命名Breaker
。谁知道它会破坏我的代码?)[B]
这将使遗漏limit
变得不可能。[C]
这是我现在将使用的替代方法。[D]
只是 [C] 内联。[E]
如果不合适,请进行类型转换。我不喜欢这个。我宁愿推断类型。
我的问题是:为什么它不起作用?或者这是一个错误?或者我可以/应该以某种方式改进/纠正Breaker
/BaseOptions
打字?如果是这样,怎么做?
编辑 1
我的tsconfig.json
:
{
"compilerOptions": {
"target": "es2017",
"module": "commonjs",
"moduleResolution": "node",
"noUnusedLocals": true,
"strict": true,
"experimentalDecorators": true,
"rootDir": "./",
"lib": [
"ES2017"
],
"types": [
"node"
]
}
}
解决方案
推荐阅读
- sql - 选择包含特定项目的所有交易?
- python - 如何使用 OSM/任何其他 API 获取路线/方式的坐标
- python - 为什么 Python 文件锁库会删除 Windows 上的锁文件,而不是 UNIX?
- gradle - 如何在 Gradle 多项目构建的子项目目录中执行命令?
- reactjs - Typescript eslint 禁用 no-unused-vars
- apache-spark - 使用 YARN 运行 pyspark 时应该设置 spark.executor.pyspark.memory 吗?
- javascript - ScriptEngineManager 获取最后成功的行
- javascript - useEffect 不会在路由更改时更新状态
- node.js - 将node.js服务器部署到heroku的问题
- c# - 根据另一个组合框值更改 DevExpress MVC ComboBox 选定值