microsoft / microsoft/TypeScript
Confusing in narrowing and property access on type parameter with `never` base constraint
还没有人认领这个 Issue。
- 主要语言
- Go
- 星标
- 111k
- 派生
- 14.3k
- 平均合并
- 2 天 4 小时
- 30 天内合并 PR
- 132
描述
### 🔎 Search Terms
never in record unknown constraint base property access
### 🕗 Version & Regression Information
- This is the behavior in every version I tried
### ⏯ Playground Link
https://www.typescriptlang.org/play/?ts=6.0.0-dev.20250802#code/CYUwxgNghgTiAEkoGdnwFoHtgBUCeADiADw4B88A3gFDzwD6mArgC4GsBc8OA3NQL7VqoJHETRUGbAHkARgCtwLYgGUAFlCIAaeNNbsWFEAA8WIAHbA0WXIRJ62rCjTr1kGol3WaQfQdRY7eABLcwAzEBh8IlJ4EzNLa2xokihzPDIKAF5uAG0AIkZ9VnyAXT5qULMYMKgwBBxMTAgVIjBgsODIqlp4cygAWxAuZBYYUIBzPjpQZDBxghZgzHMRscnp+BgmVfgACgJYQeQucxAAN0iASngsigAFGEwB4OQSUfHzCbI-IUCibhNCD3I5DarIWLxCxWQHNVrgDpdGDZeAgmCDEDg0gFbbmMpkXIABnKQhMBEwMBY8H+CAAghMLCxGs0ACIgWpMCAsFRgNQgAZQW5SYByRRgZRpPA6SU-UnGcmUkLmaq1erwemM5kQABCKBIvRUcVM0LQGuVWrZHK5PL5AqFZqZQMtUE53N5-KgWmozl6-SGa0+U16s3mwUWy12Hw2vVCBhtHq8vwCQQdWoAwlAIBBZHUANbEA1GhIw1NO9ku63uu05Uus8uu+MCr0ovawCYnJURKJ2VRkG53VFPF5vYgyipkilUqqRVV0hnmoEFuiGqGJdXzx11q1u22Cmsbi31yu75tFk3rzVA3UjlQ+ui4ri1iAZrM5sD529JmkXhd1uYLJYVlUM81yfZ0GyrKAURcPoMQDaMZhAf8w0AyN1i+TY5l3RNegfH9N2fTNszzXs-AqERoDEMIdnFCN4CgA9F0LVcS0YrcKx3D17TYiBwOPD1mz2ShYKGHQQwAiMdCwgSth2eB+EfHi2WQ8MgNvK5FMvZpSLlBUqWo8xaJWej+ggPBkFeLUl24ECYS1eF2k6SIvWXWykhFBQlFHdIdC1NEMSxcgyEElguBwKTIK8G4YLAFZRioESQDEpDQ1U8x5KFFhNjgFgmBgdKGK0iAhN6Og-SS0r4HElDJMq6Sm0qvCUDwQz9kOdEBmQfs7zoXqOn2fJySqfIlXgdrjngAAySbqTsTAwjG0FkAAOiG5VbiyHJ8ijL58miyresWjq0ByGDDsO5bLvGzqXPOuh+E2Q7BDunK8oKgB3KBgipFhltxA4lquR75Nu-ggYEIA
### 💻 Code
```ts
declare class ZodType {
_output: T;
}
declare class ZodObject extends ZodType {
_shape: Shape;
}
type inferType> = T["_output"];
interface ToolSpecifier {
name: string;
description: string;
run: (params: never) => Promise;
}
type ToolParameters = Parameters[0];
export type AgentToolDefaultSchema = ZodObject;
export interface AgentToolBase<
S extends AgentToolDefaultSchema = AgentToolDefaultSchema,
> {
name: string;
description: string;
inputSchema: S;
}
type AgentToolCallback<
S extends AgentToolDefaultSchema = AgentToolDefaultSchema,
> = (args: inferType) => Promise;
export interface AgentTool<
S extends AgentToolDefaultSchema = AgentToolDefaultSchema,
> extends AgentToolBase {
run: AgentToolCallback;
}
type AgentToolDescription = {
name: string;
description: string;
schema: S;
run: AgentToolCallback;
};
declare function agentTool<
S extends AgentToolDefaultSchema = AgentToolDefaultSchema,
>({ name, description, schema, run }: AgentToolDescription): AgentTool;
export function analysisTool<
T extends ToolSpecifier,
S extends ZodObject>,
>(t: T, schema: S) {
const { name, description } = t;
return agentTool({
name,
description,
schema,
run: async (params) => {
if ("point" in params && typeof params.point === "string") {
params = {
...params,
};
}
return await t.run(params);
},
});
}
```
### 🙁 Actual behavior
```ts
Property 'point' does not exist on type 'inferType & Record<"point", unknown>'.(2339)
```
### 🙂 Expected behavior
This should be allowed or a better error should be reported
### Additional information about the issue
This stems from inconsistent treatment of `never`:
```ts
declare const test: never;
if ("foo" in test) { // ok
}
test.foo; // error
test["foo"]; // ok
const { foo } = test; // ok
```
but given this whole thing happens at generic level it's not even apparent to the user they deal with a type parameter that has a `never` base constraint and that this might be the reason behind this confusing error
贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
调研方向
首先运行链接的 TypeScript Playground 复现,并将泛型 narrowing 和属性访问诊断与 issue 中独立的 `never` 示例进行比较。跟踪 checker 对 `"point" in params` 分支的行为;当报告的行为变得一致,或诊断清楚地解释底层类型约束时,即视为完成。
由索引模型根据 Issue 内容生成。
评估
- 技术栈
- typescript
- 领域
- compilers
- Issue 类型
- 缺陷
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 活跃度
- 停滞
- 描述清晰度
- 基本清楚
- 新手友好度
- 35/100