microsoft / microsoft/TypeScript

Confusing in narrowing and property access on type parameter with `never` base constraint

Aperta
#62,178 1 commento 0 reazioni 0 assegnatari Vedi su GitHub
Domain: check: Control Flow Help Wanted Possible Improvement
Lingua principale
Go
Stelle
111k
Fork
14.3k
Merge medio
2g 4h
PR unite (30g)
132

Descrizione

### 🔎 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

Guida per i contributori

Apri la guida per i contributori

Direzione di ricerca

Inizia eseguendo la riproduzione collegata di TypeScript Playground e confronta le diagnostiche del narrowing generico e dell’accesso alle proprietà con gli esempi autonomi di `never` nell’issue. Traccia il comportamento del checker per il ramo `"point" in params`; il lavoro è completato quando il comportamento segnalato è reso coerente oppure la diagnostica spiega chiaramente il vincolo di tipo sottostante.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
typescript
Ambito
compilers
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.