7.0 regression: inherited members are sorted by position, so an empty subinterface changes assignability
I maintainer di solito rispondono entro 1 giorno
@timurzvural ci sta già lavorando.
Dal 30/10/2026.
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 25/100
- Tipo di issue
- Bug
- Chiarezza
- Specificata chiaramente
- Stato di attività
- Ferma
- Stack tecnologico
- typescript
- Ambito
- compilers
Direzione di ricerca
Start by reviewing getNamedMembers in 7.0.2 or createMemberLayout on main, then compare how inherited members are ordered in the reproduction's deep.ts. Run tsc --noEmit --pretty false deep.ts and check whether wideC produces the same assignability error as wideB; an open linked pull request indicates work is already underway.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
🔎 Search Terms
inherited members order, member order, property order, interface extends, empty subinterface, variance, unmeasurable, getNamedMembers, createMemberLayout, missing TS2322, 7.0 regression
🕗 Version & Regression Information
- This changed between versions 6.0.3 and 7.0.2
- Still present in 7.1.0-dev.20261030.1.
- microsoft/typescript-go#1987 (first in
@typescript/native-preview7.0.0-dev.20251031.1) fixed this for one level of inheritance (Bbelow), but not for two (C).
⏯ Playground Link
No response
(Reproduction repo can be found here - it doesn't seem like Playground runs an applicable version for this issue).
💻 Code
export const empty: C<string> = {};
declare const narrowB: B<{ a: string }>;
export const wideB: B<{ a: string; b?: number }> = narrowB;
declare const narrowC: C<{ a: string }>;
export const wideC: C<{ a: string; b?: number }> = narrowC;
interface A<T> {
inherited: () => T;
}
interface B<T> extends A<T> {
own: (x: T) => Required<T>;
}
interface C<T> extends B<T> {}
Run with tsc --noEmit --pretty false deep.ts and no tsconfig, since strict is the default. empty is only there for its message, which lists C's members in the order the checker compares them.
🙁 Actual behavior
With 7.0.2 and 7.1.0-dev.20261030.1, wideC compiles, though C adds nothing to B and the same assignment to B is an error:
deep.ts(1,14): error TS2739: Type '{}' is missing the following properties from type 'C<string>': inherited, own
deep.ts(3,14): error TS2322: Type 'B<{ a: string; }>' is not assignable to type 'B<{ a: string; b?: number | undefined; }>'.
The types returned by 'own(...)' are incompatible between these types.
Property 'b' is missing in type 'Required<{ a: string; }>' but required in type 'Required<{ a: string; b?: number | undefined; }>'.
🙂 Expected behavior
wideC is an error, like wideB, as in 6.0.3:
deep.ts(1,14): error TS2739: Type '{}' is missing the following properties from type 'C<string>': own, inherited
deep.ts(3,14): error TS2322: Type 'B<{ a: string; }>' is not assignable to type 'B<{ a: string; b?: number | undefined; }>'.
The types returned by 'own(...)' are incompatible between these types.
Property 'b' is missing in type 'Required<{ a: string; }>' but required in type 'Required<{ a: string; b?: number | undefined; }>'.
deep.ts(5,14): error TS2322: Type 'C<{ a: string; }>' is not assignable to type 'C<{ a: string; b?: number | undefined; }>'.
The types returned by 'own(...)' are incompatible between these types.
Property 'b' is missing in type 'Required<{ a: string; }>' but required in type 'Required<{ a: string; b?: number | undefined; }>'.
Additional information about the issue
C has no members of its own, so all of its properties are inherited, and they are sorted by declaration position (getNamedMembers in 7.0.2, createMemberLayout on main): inherited, declared in A, comes before own, declared in B. 6.0 takes C's inherited members from B in B's order, which puts B's own members first: own, inherited.
The order changes assignability through variance measurement, which relates C<Sub> to C<Super> and back member by member, stopping at the first member that fails. Required<T> in own marks T unmeasurable (the -?), but only when relating C<Super> to C<Sub>, and that direction fails at inherited first when inherited comes first. T is then measured plain invariant: --generateTrace shows B as [in out (unmeasurable)] and C as [in out]. Invariant, wideC passes because { a: string } and { a: string; b?: number } are each assignable to the other, while wideB gets the structural check that finds own's return types incompatible.
A fix: order inherited members by base type, and within a base type in that base's order, as 6.0 does.
Related, and already fixed on main: in 7.0.2 the order could also depend on other files. An inherited member counted as the interface's own when its text range fell inside the range of one of the interface's declarations in another file, such as a module augmentation, because isDeclarationContainedBy doesn't compare files, so a longer comment in an augmentation could make an assignment compile. #64915 replaced that check for classes and interfaces (first in 7.1.0-dev.20261024.1). I can share a repro if it matters for 7.0.
Found because a library relies on a -? member like own for exact assignments between instantiations of its schema type, and interfaces extending that type lost them on 7.0.
- Lingua principale
- Go
- Stelle
- 112k
- Fork
- 15.4k
- Merge medio
- 2g 21h
- PR unite (30g)
- 126
Preparare l'ambiente
Avvia il container di sviluppo del progetto nel browser, con il tuo account GitHub.
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di microsoft/TypeScript
-
Won't Fix
Difficoltà 2/5 1-3 ore Idoneità per principianti 62/100
microsoft/TypeScript#65107 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Native API: formatDiagnosticsWithColorAndContext drops related information without a file locationForse già presa @timurzvural l’ha presa oggi. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
microsoft/TypeScript#65087 ·
I maintainer di solito rispondono entro 1 giorno
-
TS7 LSP: documentHighlight returns nothing when the file path contains '@'Forse di nuovo libera Una pull request per questa issue è stata chiusa senza essere unita. ApertaBug
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
microsoft/TypeScript#64758 ·
I maintainer di solito rispondono entro 1 giorno
-
Language server (tsc --lsp) exits with code 1 after `shutdown` and `exit`Forse già presa @rajnish-verma-22172 l’ha presa 12 giorni fa. ApertaBug
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
microsoft/TypeScript#64742 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Class names `eval` and `arguments` are not reported as invalid strict mode bindingsForse già presa @dmety l’ha presa 26 giorni fa. ApertaBug
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
microsoft/TypeScript#64661 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di microsoft/TypeScript
Issue simili
-
bug good first issue help wanted
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
-
[mesheryctl] design delete fails when passing file or URL as positional argumentForse già presa Una pull request collegata a questa issue è aperta o già unita. Apertacomponent/mesheryctl kind/bug language/go
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
meshery/meshery#22772 · 3 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
backend security size:S
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
limitlessprojects/Go-Hybrid#3342 ·
I maintainer di solito rispondono entro 1 giorno
-
status/ready type/bug
Difficoltà 2/5 1-3 ore Idoneità per principianti 65/100
buildpacks/pack#2733 ·
I maintainer di solito rispondono entro 1 giorno