TypeScript 当Weak类型与ThisType相交时,未被拒绝,

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

🔎 搜索词

  • function overload
  • ThisType
  • this

🕗 版本与回归信息

  • 这是一次崩溃

⏯ Playground 链接

https://www.typescriptlang.org/play?#code/JYOwLgpgTgZghgYwgAgGIHt3IN4ChnJwBcyAzmFKAOa4C+uAJhAgDZxQowCuICYw6EMm4gADAAp2VEuICUyALwA+ZOPzIAZGkzqtAFQAWwUnoCeABwgAeDOiW5ZskgDd0wBo2ZsOwnnwFCIhJSMrrIAArs-HAsNpj2BPpGJhbWtvaOLm4euEHieAD0BcgAegD86sTIAOQAjNV0srk8EnKKKvm4RaUVBFV1DbSOXcUAAmCkALQQAB6WfNNQUOhQzWLibcqqhcXllSS1jU1AA

💻 代码

interface Foo {
  a: string
}
declare function fun0(arg: () => (
  & Foo
  & ThisType<Foo>
)): void
declare function fun0(arg: (
  & Partial<Foo>
  & ThisType<Foo>
)): void

fun0({
// ^? function fun0(arg: (Partial<Foo> & ThisType<Foo>)): void (+1 overload)
  a: '1'
})
fun0(() => ({
// ^? function fun0(arg: () => (Foo & ThisType<Foo>)): void (+1 overload)
  a: '1'
}))
// @ts-expect-error
fun0(() => ({
// ^? function fun0(arg: (Partial<Foo> & ThisType<Foo>)): void (+1 overload)
  a: 1
}))

当我用类似于 {} 的类型与 ThisType 求交时,它总是解析为这个声明。

🙁 实际行为

overload to function fun0(arg: (Partial<Foo> & ThisType<Foo>)): void (+1 overload)

🙂 预期行为

overload to function fun0(arg: () => (Partial<Foo> & ThisType<Foo>)): void (+1 overload)

关于问题的附加信息

当我注解掉 ThisType 的交集时,它可以正常工作。

omqzjyyz

omqzjyyz1#

这些都不是错误:

interface Foo {
  a: string;
}
declare function fun0(arg: Partial<Foo> & ThisType<Foo>): void;

fun0(() => ({
  a: "1",
}));
fun0(() => ({
  a: 1,
}));
fun0(function () {
  this.a; // errors
  return {
    a: 1,
  };
});
3bygqnnd

3bygqnnd2#

我理解你描述的情况,但我认为一个 {} 类型的元素,即使与 ThisType 相交,也应该保持其原始逻辑并保持不变,就好像没有 ThisType 参与一样。
正如我在 "关于此问题的附加信息" 中展示的那样。

ftf50wuq

ftf50wuq3#

在这里,我们可以看到实际上对于这种类型有一个更准确的类型错误消息,但它被忽略了,以便寻找一个最佳可能的匹配,而不是在编译期间提醒我们这个错误。我认为这种行为并不完全合适。

rnmwe5a2

rnmwe5a24#

我不是说这完全符合直觉。我只是注意到了一些额外的测试用例(没有重载/交集)让我感到惊讶。
文档中提到:
ThisType标记接口只是一个在lib.d.ts中声明的空接口。除了在对象字面量的上下文类型中被识别外,该接口的行为就像任何空接口一样。
所以这似乎与“像任何空接口一样”的行为是一致的:

interface Foo {
  a: string;
}
interface Bar {}

declare function fun0(arg: Partial<Foo> & Bar): void;

// all of those are OK because of `& Bar`
fun0(() => ({
  a: "1",
}));
fun0(() => ({
  a: 1,
}));
fun0(function () {
  return {
    a: 1,
  };
});

我不太确定为什么它表现得像这样,而且它与type Bar = {}不一致。也许这是typeinterface之间的另一个微妙差异。

798qvoo8

798qvoo85#

它的行为似乎与预期相符,但我仍然认为这是一个应该修复的问题。
该接口表现得像任何空接口一样。

wz1wpwve

wz1wpwve6#

更简洁的:

interface Foo { a: string }

// No error, but should
const m1: Partial<Foo> & ThisType<{ x: string }> = () => null;

// Correctly errors
const m2: Partial<Foo> = () => null;

相关问题