Generic class in a reference cycle measured invariant in 7.1: `Link<Sub>` no longer assignable to `Link<EntityBase>` (@sap-cloud-sdk/odata-common)

Ouverte
#64,995 0 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Les mainteneurs répondent en général sous 1 jour

@1-DARK y travaille déjà.

Depuis le 29/10/2026.

  • #65030 par @1-DARK — ouverte

Évaluation

Difficulté
4/5
Temps estimé
3-5 jours
Accessibilité débutants
46/100
Type d'issue
Bug
Clarté
Clairement spécifiée
Activité
Active
Stack technique
go, typescript
Domaine
backend, compilers

Piste de recherche

Start by comparing TypeScript 7.0.2 and 7.1 behavior with the supplied minimal reproduction and strict tsconfig; the issue identifies variance computation and a possible connection to microsoft/typescript-go#4820. Trace the reported Link → EntityApi → RequestBuilder → Selectable reference cycle and inspect the variance elaboration path. Done means the reproduction compiles as it did on 7.0.2 while preserving the reported assignability behavior.

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

Description

🔎 Search Terms

variance circularity, circular variance class, variance computed invariant, subclass type argument not assignable, @sap-cloud-sdk Link not assignable, 7.1 variance regression

🕗 Version & Regression Information
  • This changed between versions 7.0.2 (gitHead 2bd066d8) and 7.1.0-beta (gitHead 3e923636)
  • passes on 7.0.2, fails on 7.1.0-beta, 7.1.0-dev.20261022.1, 7.1.0-dev.20261027.1 and 7.1.0-dev.20261028.1
  • same result with --singleThreaded
⏯ Playground Link

n/a - needs the @sap-cloud-sdk/odata-common package

💻 Code
// repro.ts - @sap-cloud-sdk/[email protected], node 24.18
import type { DefaultDeSerializers, EntityApi, EntityBase, Link } from '@sap-cloud-sdk/odata-common';

type D = DefaultDeSerializers;
declare class Sub extends EntityBase { readonly _oDataVersion: 'v2'; id: string }
declare const l: Link<Sub, D, EntityApi<EntityBase, D>>;
export const l2: Link<EntityBase, D, EntityApi<EntityBase, D>> = l;
// tsconfig.json
{
  "compilerOptions": { "strict": true, "noEmit": true, "module": "nodenext", "target": "es2022", "skipLibCheck": true },
  "files": ["repro.ts"]
}

npm i @sap-cloud-sdk/[email protected] && tsc -p .

🙁 Actual behavior
repro.ts(6,14): error TS2322: Type 'Link<Sub, DefaultDeSerializers, EntityApi<EntityBase, DefaultDeSerializers>>' is not assignable to type 'Link<EntityBase, DefaultDeSerializers, EntityApi<EntityBase, DefaultDeSerializers>>'.
  Property 'id' is missing in type 'EntityBase' but required in type 'Sub'.
🙂 Expected behavior

no error, like 7.0.2. Link only uses EntityT in covariant positions (readonly _entity: EntityT, readonly _entityApi: EntityApi<EntityT, DeSerializersT>), and EntityApi<Sub, D> is assignable to EntityApi<EntityBase, D> on 7.1 too

Additional information about the issue

copying Link and Selectable from the package into local files makes the same assignment pass on 7.1, so it seems to need the package's own reference cycle Link -> EntityApi<E> -> RequestBuilder<E> -> select(Selectable<E>) -> Link: the elaboration goes straight from Link to EntityBase vs Sub, as if Link's variance for EntityT was measured invariant without falling back to a structural check

possibly related: microsoft/typescript-go#4820 "Order variance computation by associated type symbol" (merged 2026-08-05) is in 7.1 (its port d20f192a in this repo is an ancestor of all four 7.1 gitHeads above) and not in 7.0.2 (2bd066d8 branches from typescript-go main at 52168999, 2026-07-08)

in a real service this breaks every SAP Cloud SDK call that passes a generated entity's request builder or link where the SDK takes the EntityBase form (new ODataBatchRequestBuilder(...), new BatchChangeSet(...), .select(SomeApi.schema.TO_X.select(...)), .filter(SomeApi.schema.TO_X.filter(...))): 41 errors in 26 files, all of them TS2345/TS2769 that 7.0.2 accepts

Langage dominant
Go
Étoiles
112k
Forks
15.4k
Merge moyen
3 j 1 h
PR mergées (30 j)
136

Préparer son environnement

Ouvrir dans Codespaces

Lance le conteneur de développement du projet dans votre navigateur, avec votre propre compte GitHub.

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.

Autres issues de microsoft/TypeScript

Toutes les issues de microsoft/TypeScript

Issues similaires

Plus d'issues Go

Recevez les nouvelles issues par e-mail

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