microsoft / microsoft/TypeScript
[3.5.0-dev.20190516] Incorrect type error for mixin
Nessuno ha ancora preso questa issue.
- Lingua principale
- Go
- Stelle
- 111k
- Fork
- 14.3k
- Merge medio
- 2g 4h
- PR unite (30g)
- 132
Descrizione
When using the mixin pattern, there are 2 main notations to define the type of the mixin entity.
The mixin pattern:
export type AnyFunction<A = any> = (...input : any[]) => A
export type AnyConstructor<A = object> = new (...input : any[]) => A
export type Mixin<T extends AnyFunction> = InstanceType<ReturnType<T>>
export const Box = <T extends AnyConstructor<object>>(base : T) =>
class Box extends base {
value : any
}
1st notation:
export type Box = Mixin<typeof Box> {}
2nd notation:
export interface Box extends Mixin<typeof Box> {}
The 1st notation can not be used for recursive definitions (#29872). Because of that we primarily use 2nd notation. It works fine in most cases, however I found a case, when it produces invalid type error. The full snippet to reproduce the problem below.
Note:
- The typechecker correctly figures out that there's no
zxcproperty onthis, inside theobservemethod ofQuarkmixin. - In that method, it does not complain about the
this.valueusage - It does complain, when
valueis used on function argument - If you'll switch the
Quarkmixin to the 1st notation, the error will disappear
Expected behavior:
- No type errors for the definition of
testfunction below
export type AnyFunction<A = any> = (...input : any[]) => A
export type AnyConstructor<A = object> = new (...input : any[]) => A
export type Mixin<T extends AnyFunction> = InstanceType<ReturnType<T>>
export const Box = <T extends AnyConstructor<object>>(base : T) =>
class Box extends base {
value : any
}
export interface Box extends Mixin<typeof Box> {}
export const Observable = <T extends AnyConstructor<object>>(base : T) =>
class Observable extends base {
observe () : Quark {
return
}
}
export interface Observable extends Mixin<typeof Observable> {}
export const Quark = <T extends AnyConstructor<Box & Observable>>(base : T) =>
class Quark extends base {
observe () : Quark {
// No error here!
this.value
// error: Error:(28, 14) TS2339: Property 'zxc' does not exist on type 'Quark'.
this.zxc
return
}
}
export interface Quark extends Mixin<typeof Quark> {}
const test = (a : Quark) => a.value // <-- Error:(35, 28) TS2339: Property 'value' does not exist on type 'Quark'.
Guida per i contributori
Apri 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.
Direzione di ricerca
Inizia compilando il reproducer completo in TypeScript presente in questo issue e confronta le due notazioni dei mixin di Quark. Segui come il checker risolve la proprietà value ereditata all’interno di Quark e sull’argomento della funzione di test. Il lavoro è completato quando la seconda notazione non produce alcun errore di tipo per a.value, mentre l’accesso non valido a this.zxc continua a segnalare un errore.
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à
- Attiva
- Chiarezza
- Specificata chiaramente
- Idoneità per principianti
- 52/100