TypeScript 类型错误:使用Map类型(部分)&此类型&查找类型

3df52oht  于 6个月前  发布在  TypeScript
关注(0)|答案(3)|浏览(66)

TypeScript版本: 夜间版
**搜索词:**Map类型,部分,this,查找类型
代码

class A {
  state = { foo: "foo", bar: 42 };

  something(): Partial<A["state"]> {
    return { foo: "changed" }; // works
  }
}

class B {
  state = { foo: "foo", bar: 42 };

  something(): Partial<this["state"]> {
    return { foo: "changed" }; // fails
  }
}

class C {
  state = { foo: "foo", bar: 42 };

  something(): Partial<this["state"]> {
    return { foo: "changed", bar: 123 }; // works
  }
}

预期行为:

应该进行类型检查。

实际行为:

Type '{ foo: "changed"; }' is not assignable to type 'Partial<this["state"]>'.(2322)

**示例链接:**Example
**相关问题:**尝试搜索Partial this,未找到任何相关问题。

b09cbbtk

b09cbbtk1#

B 的错误是 #24946 的重复,而 #24946#13442 的重复。多态的 this 本质上是一个泛型类型参数,它扩展了当前类,你遇到了 the situation where subtypes can narrow existing properties as well as adding new properties

作为一个例子,B 的错误警告你如下内容:

class Bee extends B {
  state = { foo: "alwaysFoo", bar: 0 } as const; // string literal type!
}
const b = new Bee().something().foo;
// typeof b is ("alwaysFoo" | undefined) at compile time
// but it's "changed" at runtime, leading to this mess:
if (b) ({ alwaysFoo: "okay" }[b].toUpperCase()); // runtime error

但是,我期望 CB 相同的方式失败,原因相同:

class Sea extends C {
  state = { foo: "alwaysFoo", bar: 0 } as const
}
const c = new Sea().something().foo;
// typeof c is ("alwaysFoo" | undefined) at compile time
// but it's "changed" at runtime, leading to this mess:
if (c) ({ alwaysFoo: "okay" }[c].toUpperCase()); // runtime error

这部分似乎与 #33181 重复,与 #17110 有关,其中对受限制的泛型类型的属性读取会扩大到泛型约束的属性。这是方便的,但不可靠。我不确定为什么 C 会出现这个问题,而不是 B,所以也许这里还有一些非重复的问题。

无论如何,这是我的意见。祝你好运!

2uluyalo

2uluyalo2#

关于为什么会出现这种情况,我有一些理论,但它们都不是特别好。

kx1ctssn

kx1ctssn3#

  1. class A 并未使用通用Map类型(它只是引用了 A),因此整个部分使用的是与标准 propertiesRelatedTo 相关的路径。
  2. class B 使用了通用Map类型(因为它引用了 this 类型)。keyof this['state'] 也被视为通用索引类型,所以我们在这里快速返回 true
  3. class C 基本上与 class B 相同 它能够在这里利用快速路径。
    我可能遗漏了一些细微之处 - 但感觉这应该在某种程度上有效。即使 this 是一个泛型类型,整个赋值也应该是有效的,因为它只关注此时已经可用的信息。

相关问题