microsoft / microsoft/TypeScript
Assertion methods (`asserts this is`) are not CFA'd without error
Nadie ha tomado este issue todavía.
- Lenguaje dominante
- Go
- Estrellas
- 111k
- Forks
- 14.3k
- Merge medio
- 2 d 4 h
- PR fusionados (30 d)
- 132
Descripción
TypeScript Version: 4.0.5, 4.1.0-beta, 4.2.0-dev.20201112
Search Terms:
- Multiple assertion methods
- "asserts this is"
- assertion "cfa"
Code
class X<T, Locked extends boolean> {
public x: null | T | (Locked extends true ? 1 : 2) = null
public assert<U>(): asserts this is X<U, Locked> { }
public lock(): asserts this is X<T, true> {}
}
const x: X<string | number, false> = new X<string | number, false>()
x.assert<string>()
// x is X<string, false> here
x.lock()
Expected behavior:
Either:
- After
x.lock(),xis narrowed toX<string, true> - Or, the
x.lock()line throws at compile-time due to not being CFA'd
Actual behavior:
After x.lock(), x is narrowed to X<string, false> & X<string | number, true>.
Analysis:
x being typed as X<string, false> & X<string | number, true> shows that the x.lock() narrows from the original type (X<string | number, false>) instead of the narrowed type at that position (X<string, false>).
If instead a "top-level" assertion function is used the type is properly narrowed:
class X<T, Locked extends boolean> {
public x: null | T | (Locked extends true ? 1 : 2) = null
public assert<U>(): asserts this is X<U, Locked> { }
public lock(): asserts this is X<T, true> {}
}
const x: X<string | number, false> = new X<string | number, false>()
x.assert<string>()
// x is X<string, false> here
declare function lock<T>(v: X<T, boolean>): asserts v is X<T, true>
lock(x)
This leads me to believe this is an issue with the x.lock() call not being CFA'd, in which case the correct behavior would be to throw ts(2775) on the x.lock() line.
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 ejecutando la reproducción proporcionada en TypeScript Playground y compara el narrowing del flujo de control después de x.assert<string>() y x.lock(). Investiga cómo el compilador maneja los métodos asserts this is y el tipo de intersección reportado. Se considera completado cuando la segunda assertion hace narrowing a X<string, true> o informa del error esperado en tiempo de compilación, con cobertura de regresión para el ejemplo.
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
- Estancado
- Claridad
- Bastante claro
- Aptitud para principiantes
- 35/100