TypeScript 不正确的快速信息(任何)用于从联合中的对象类型起源的属性,

brqmpdu1  于 3个月前  发布在  TypeScript
关注(0)|答案(4)|浏览(36)

🔎 搜索词

  • union
  • function return type
  • quickinfo
  • this

🕗 版本与回归信息

  • 这是一次崩溃

⏯ Playground链接

https://www.typescriptlang.org/play?#code/CYUwxgNghgTiAEAzArgOzAFwJYHtVJxwAooAGALniIEp4BeAPngG8CdKBnDGLVAcwA08AEaxKqZAFthIGPAC+8AD5IoEDiGqUAbjizAAUIkJEa9JkWYH4bSgHIAjHYHX4fEBhGwzVmzYD0-gB6IfAAKgCeAA4Idlw8-HbwWBzwqDieUBwcWHyoUMIQCBg48BjRsRLSsnYAdEQATADMDQ3UrjZwGMgw+BgAFim1xjgd8IF+k35BAPyu8gby1O0GoJCwCCjo2HheMCQUVLSMLLbw8byCe5zclwrKquqaOnqGovtmJ5auI-ZOLjZ3J53j4xl0en1BhxhoQxhMppNZvNFssDEA

💻 代码

当我在函数的返回类型中使用 union 类型时,类型检查仍然有效,但似乎通过 this 上的属性描述符获得的属性类型不再正常工作。这里的类型查询调用了 TypeScript服务quickinfo 命令。

declare function foo(a0: () => { foo: string, bar: number } | false): void
foo(() => ({
  foo: '1',
  get bar() {
    //^^^ Type 'string' is not assignable to type 'number'.(2322)
    return this.foo
    //          ^? foo: any
  }
}))

declare function bar(a0: () => { foo: string, bar: string } | false): void
bar(() => ({
  foo: '1',
  get bar() {
    return this.foo
    //          ^? foo: any
  }
}))

当我在样本中进一步测试时,发现了一些奇怪的事情。

🙁 实际行为

foo: any

🙂 预期行为

foo: string

关于问题的附加信息

  • 无响应*
dfddblmv

dfddblmv1#

尽管ThisType可以帮助我解决问题,但我仍然认为这是一个需要解决的问题。为什么用户必须明确声明它,而不是推断出我需要什么?这里的所需类型非常明显。

type WithThis<T> = T & ThisType<T>

declare function foo(a0: () => WithThis<{ foo: string, bar: number }> | false): void
foo(() => ({
  foo: '1',
  get bar() {
    type T0 = [typeof this.foo] extends [string] ? true : false
    //   ^? true
    type T1 = typeof this.foo extends string ? true : false
    //   ^? true
    return +this.foo
    //          ^? string
  }
}))

Playground链接

but5z9lq

but5z9lq2#

为了清晰起见,无需重命名冲突的标识符:

declare function func1(a0: () => { foo: string, bar: number } | false): void
declare function func2(a0: () => { foo: string, bar: string } | false): void

func1(() => ({
  foo: '1',
  get bar() {
    //^^^ Type 'string' is not assignable to type 'number'.(2322)
    return this.foo
    //          ^?
  }
}))

func2(() => ({
  foo: '1',
  get bar() {
    return this.foo
    //          ^?
  }
}))
rjee0c15

rjee0c153#

这似乎只是一个语言服务显示问题——从错误中我们可以看出,类型实际上是被正确计算的。

mv1qrgav

mv1qrgav4#

这是一个有趣的案例😅
当解析类型 getContextualThisParameterType 时,得到 containingLiteral 并尝试 getApparentTypeOfContextualType 。由于它需要 getContextualTypeForReturnExpression 才能获取这个未注解的箭头函数,所以无法获取。由于它是一个未注解的箭头函数,其签名仍然设置为 resolvingSignature ,因此无法从中检索到上下文类型。由于没有上下文类型,因此通过 checkExpressionCached(containingLiteral) 创建了包含对象字面量的类型。
但是当语言服务要求在此位置获取类型时...箭头的签名不再是 resolvingSignature 。因此,我们在这里得到了 contextualTypethis ...并且它是一个联合( { foo: string, bar: number } | false )。由于 .foo 不在那个联合上,我们得到了一个错误类型并将其显示为 any
修复这个问题有点棘手-最好复制此处类型检查的非常精确的行为,但我不确定当场如何做到这一点。我考虑过过滤这个 contextualType ,它是一个联合,但我仍然担心这两种场景之间其他行为不匹配的问题。

相关问题