microsoft / microsoft/TypeScript
[3.5.0-dev.20190516] Incorrect type error for mixin
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Go
- Estrellas
- 111k
- Forks
- 14.4k
- Merge medio
- 1 d 19 h
- PR fusionados (30 d)
- 117
Descripción
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'.
Guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Línea de trabajo
Comienza compilando el reproducer completo de TypeScript incluido en este issue y compara las dos notaciones de mixin de Quark. Sigue cómo el checker resuelve la propiedad value heredada dentro de Quark y en el argumento de la función de prueba. Se considera terminado cuando la segunda notación no produce ningún error de tipo para a.value, mientras que el acceso no válido a this.zxc sigue informando de un error.
Escrito por el modelo de indexación a partir del texto del issue.
Evaluación
- Stack tecnológico
- typescript
- Área
- compilers
- Tipo de issue
- Error
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Estado de actividad
- Activo
- Claridad
- Bien especificado
- Aptitud para principiantes
- 52/100