microsoft / microsoft/TypeScript

`silentNeverType` leak through return type inference

未关闭
#62,824 2 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

Bug Domain: check: Type Inference Help Wanted
主要语言
Go
星标
111k
派生
14.3k
平均合并
2 天 4 小时
30 天内合并 PR
132

描述

### 🔎 Search Terms

silent never leak reverse mapped types nested calls return type inference

### 🕗 Version & Regression Information

- This is the behavior in every version I tried

### ⏯ Playground Link

https://www.typescriptlang.org/play/?noEmit=true&ts=6.0.0-dev.20251202#code/C4TwDgpgBAaghgGwK4QM4B4AqA+KBeKTAbQGsIQB7AM0IF0BuAKEdEigFk4BjACwEsAdhADCFAcAgAPYPigAlCFwoAnACbpUwZYIDmAGihwBIbE0aCJyqt2gAFOMrgBbCJb4AvCKoDyAIwBWijIA3oxQUKwQAFxQmtoCOkzhYA7OqAD8MUgCJAIUAO4CTAC+zJFQAIJcwHxiAGLZ1bUC6GGEouJSMl0QAqqoHNz8Qh0S0nptmPaOTgM9fQPTzq4Q2p4+AUFEAEQpM6jbtFAAPlDZqhBUgl4T4ZhVNWJQ8-1QSy5u636B1RO4BKFwgAKaqSGKYUZdAx7NLg96oACUMQAbhQ+KoklAAPoUJDALH3JpiTKEB7NEpmcqYCjvFZrLzfIKtO60z5eThgZ7SXqvBRKNTM8KxLS6W5C1mrDwMzbVHYw2aHE5nPqXa6qNrYP6yeDINDoQFQIgAaSggigZEoNCmqQ+kvWHKgADJhfEdLQYgbwpEYkbMckbag4Ta6VLVBzjQw2sUSqYyuBoKIEAggmSxBhJpDpFyJAtBrxrpngGLrftszzFsG2RsfsA5QHFadzqqhKotQQgW1PVAlJ1xm1wr0AI4oFBi4oe-vdsRjYDgwt+54CYcQFAxIHcR4CNcI-C4VHond4PdojFRsXywOEeETQ-H9FmC5cBAOaBURqbxfLlCpgTpu6Fstc04fMRmnKFJnhQDXglelqy2XZ6yORsVSuFtix-KCKxmEMvhlGQCBg0NGV+RhsA7cIlCTIIYkTZNqh-DAITA8YrwDTVGCRSoiQEBoBG4rBCwMEs0iEn9Y0YR9n2UV932aWJXCQMBBSY3tum5IChgLZii0mBjMPkRQVHUSc4lFSdCNwms632BtlQuVCvA1WRgmKP4gQNSJUDFDdmi8xhxygDz4wyD0p1UkkVJnKBozaHy0xJLtjVNARzXIahSW41B3S4zdeP4yd-20sUhQyzdUAjYqhWpCzpRrLAGOwSdY3CGLik4-dT0YVAFLAdzYsyicStUCgAGVgCQKgqBiIcRwgBigSBLFoQDGIBCQJxfFWW9ArascJjasxuvG3qDTi39BqFYaxomqbP1m+bFuW-ZVvWzblG2lyEUq4bvGAHhVmuya1yWqALxiUyEg+1yz38hFDp6vrwjOy8uyu8agbulc5syhaQbBqA1o2rbdx2r7Jx+v6AfR27FpiIwQCe2EXV0KG9thpggA

### 💻 Code

```ts
type Values = T[keyof T];

type MachineContext = Record;

interface ParameterizedObject {
type: string;
params?: unknown;
}

type ActionFunction<
TContext extends MachineContext,
TParams extends ParameterizedObject["params"] | undefined,
TAction extends ParameterizedObject,
> = {
(ctx: TContext, params: TParams): void;
_out_TAction?: TAction;
};

type ToParameterizedObject<
TParameterizedMap extends Record<
string,
ParameterizedObject["params"] | undefined
>,
> = Values<{
[K in keyof TParameterizedMap & string]: {
type: K;
params: TParameterizedMap[K];
};
}>;

type CollectActions<
TContext extends MachineContext,
TParams extends ParameterizedObject["params"] | undefined,
> = (
{
context,
enqueue,
}: {
context: TContext;
enqueue: (action: () => void) => void;
},
params: TParams,
) => void;

declare function enqueueActions<
TContext extends MachineContext,
TParams extends ParameterizedObject["params"] | undefined,
TAction extends ParameterizedObject = ParameterizedObject,
>(
collect: CollectActions,
): ActionFunction;

declare function setup<
TContext extends MachineContext,
TActions extends Record<
string,
ParameterizedObject["params"] | undefined
> = {},
>({
types,
actions,
}: {
types?: { context?: TContext };
actions?: {
[K in keyof TActions]: ActionFunction<
TContext,
TActions[K],
ToParameterizedObject
>;
};
}): void;

setup({
actions: {
doStuff: enqueueActions((_, params: number) => {}),
},
});

setup({
actions: {
doStuff: enqueueActions((_, params: number) => {}),
doOtherStuff: (_, params: string) => {},
},
});

setup({
actions: {
doStuff: enqueueActions((_, params: number) => {}),
doOtherStuff: (_: any, params: string) => {},
},
});
```

### 🙁 Actual behavior

First 2 calls mention such a relationship check failure in the error message:
```
Type 'ActionFunction' is not assignable to type 'ActionFunction'.
```

Notice **never** there. This is quite weird an unexpected as there is no `never` in sight here. It turns out this is a `silentNeverType` that leaked through.

### 🙂 Expected behavior

At the very least, I would expect it to error with consistent error messages mentioning `unknown` instead of `never`. Even better, if it could behave closer to a *very similar* version of this code: [TS playground](https://www.typescriptlang.org/play/?noEmit=true&ts=6.0.0-dev.20251202#code/C4TwDgpgBAaghgGwK4QM4B4AqA+KBeKTAbQGsIQB7AM0IF0BuAKEdEigFk4BjACwEsAdhADCFAcAgAPYPigAlCFwoAnACbpUwZYIDmAGihwBIbE0aCJyqt2gAFOMrgBbCJb4AvCKoDyAIwBWijIA3oxQUKwQAFxQmtoCOkzhYA7OqAD8MUgCJAIUAO4CTAC+zJFQAIJcwHxiAGLZ1bUC6GGEouJSMl0QAqqoHNz8Qh0S0nptmPaOTgM9fQPTzq4Q2p4+AUFEAEQpM6jbtFAAPlDZqhBUgl4T4ZhVNWJQ8-1QSy5u636B1RO4BKFwgAKaqSGKYUZdAx7NLg96oACUMQAbhQ+KoklAAPoUJDALH3JpiTKEB7NEpmcqYCjvFZrLzfIKtO60z5eThgZ7SXqvBRKNTM8KxLS6W5C1mrDwMzbVHYw2aHE5nPqXa6qNrYP6yeDINDoQFQIgAaSggigZEoNCmqQ+kvWHMMAxNADJhfEdLQYgbwpEYi63bpMckbag4Ta6VLVBzjQw2sUSqYyuBoKIEAggmSxBhJpDpFyJAtBrxrrngGLrft8zzFuG2RsfsA5SHFadzqqhKotQQgW1vVAlJ1xm1wr0AI4oFBi4pe4f9sRjYDg0tB54CccQFAxIHcR4CLcI-C4VHog94I9ojFxsXy0OEeETU-n9FmC5cBAOaBURq71frlCZgRszuUsq0LThixGecoUmeFQNeCV6XrLZdmbI5WxVK4O3LAC4JrGYIy+GUZAIBDI0ZX5GGwHtwiUNMghiVN02qACMAhKDxjvENNUYJFKiJAQGgEfisFLAwKzSMSAMTRhX3fZRP2-ZpYlcJAwEFNjB26bkwKGEt2LLSYWNw+RFBUdRZziUVZ1IwiGybfYW2VC5MK8DVZGCYo-iBA1IlQMUd2aPzGGnKAfOTDIvTnTSSQ0hcoHjNoAqzEk+2NU0BHNchqFJfjUE9Pjd0E4TZ2A-SxSFHLd1QGNyqFakbOlBssBY7BZ0TcIEuKXjj0vRhUBUsBvMS3KZwq1QKAAZWAJAqCoGIxwnCAWKBIEsWhEMYgEJAnF8VZH1CrqpwmLqzH66bBoNJLANGoVxqmma5t-RbltW9b9k27bduUfaPIRWrxu8YAeFWe7Zq3NaoBvGJLISH7PKvYKEVOgahvCK7bz7O7prBp6NyW3KVohqGoC2na9sPA6-tnAGgZB7HHtWmIjBAN7YQDWGKY8o7EaYIA). In there the third error still errors but the first two infers nicely.

### Additional information about the issue

_No response_

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

调研方向

首先复现链接的 Playground 示例,并比较三个设置调用的诊断结果,尤其关注前两个调用中泄漏的 `silentNeverType`。跟踪涉及的 TypeScript 类型推断和关系检查路径;当最初两个调用按预期进行推断,或报告一致的基于 `unknown` 的错误且不暴露 `never` 时,即表示完成。

由索引模型根据 Issue 内容生成。

评估

技术栈
typescript
领域
compilers
Issue 类型
缺陷
难度
4/5
预计耗时
3-5 天
活跃度
停滞
描述清晰度
基本清楚
新手友好度
35/100

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。