microsoft / microsoft/TypeScript

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

Ouverte
#62,178 1 commentaire 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Domain: check: Control Flow Help Wanted Possible Improvement
Langage dominant
Go
Étoiles
111k
Forks
14.3k
Merge moyen
2 j 4 h
PR mergées (30 j)
132

Description

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

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez par exécuter la reproduction liée dans TypeScript Playground et comparez les diagnostics de narrowing générique et d’accès aux propriétés avec les exemples autonomes de `never` dans l’issue. Suivez le comportement du checker pour la branche `"point" in params` ; le travail est terminé lorsque le comportement signalé est rendu cohérent ou que le diagnostic explique clairement la contrainte de type sous-jacente.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
typescript
Domaine
compilers
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.