microsoft / microsoft/TypeScript
Regression: Type T[K] as an array when sliced loses its type
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: 3.4.5
Search Terms:
array property generics
Code
export function GetArrayProp<U, K extends string, T extends Record<K, U[]>>(
state: T,
prop: K,
) {
//good
let x1: T[K] = state[prop];
//good
let x2: U[] = state[prop];
//good
let x3: U[] = state[prop].slice(0);
//error
let x4: T[K] = state[prop].slice(0);
}
While you can argue that U[] isn't necessarily assignable to type T[K]. Look at the following code.
It's hard to see how TypeFromArray<T[K]>[]'s type should be any different than T[K]
export type TypeFromArray<T> = T extends (infer R)[] ? R : never;
export function GetArrayProp<K extends string, T extends Record<K, Array<TypeFromArray<T[K]>>>>(
obj: T,
prop: K,
) {
//good
let x1: T[K] = obj[prop];
//good
let x2 = obj[prop].slice(0);
//error Type 'TypeFromArray<T[K]>[]' is not assignable to type 'T[K]'.
let x3: T[K] = obj[prop].slice(0);
}
Expected behavior:
No errors.
T[K] and U[] should be assignable to each other.
state[prop].slice(0) should be of the same type as state[prop]
TypeFromArray<T[K]>[]'s type should be not be any different than T[K]
This code works in version 3.2.4 but stopped working in 3.3.1
Actual behavior:
Error Type 'U[]' is not assignable to type 'T[K]'.
Error Type 'TypeFromArray<T[K]>[]' is not assignable to type 'T[K]'
Playground Link:
My main goal is to be able to pluck array properties and modify the arrays without losing the type T[K]
The code above is simplified to show how TS is behaving.
See my use case below.
It's hard to see how TypeFromArray<T[K]>[]'s type should be any different than T[K]
The code below used to work when using 3.2.4
import { EntityState, EntityAdapter } from '@ngrx/entity';
import { Action } from '@ngrx/store';
export type TypeFromArray<T> = T extends (infer R)[] ? R : never;
type Selector<T> = (s: T) => boolean;
function ModifyEntityFromState<T>(entityId: number, state: EntityState<T>, callBack: (acnt: T) => void): T {
const t = state.entities[entityId];
const acnt = JSON.parse(JSON.stringify(t)) as T;
callBack(acnt);
return acnt;
}
export function ModifyPropertyFromState<T, K extends keyof T>(
entityId: number,
state: EntityState<T>,
prop: K,
callBack: (a: T[K]) => T[K],
): T {
return ModifyEntityFromState( entityId, state, (acnt) => {
acnt[prop] = callBack( acnt[prop] );
});
}
export function EditArrayFromState<
T extends Record<K, Array<TypeFromArray<T[K]>>>,
K extends keyof T,
U extends TypeFromArray<T[K]>
>(
entityId: number, state: EntityState<T>, prop: K,
selector: Selector<U>,
modified: U
): T {
return ModifyPropertyFromState( entityId, state, prop, (a) => {
//Argument of type '(a: T[K]) => TypeFromArray<T[K]>[]' is not assignable to parameter of type '(a: T[K]) => T[K]'.
// Type 'TypeFromArray<T[K]>[]' is not assignable to type 'T[K]'
const idx = a.findIndex(selector);
return [
...a.slice(0, idx),
...a.slice(idx + 1),
modified
];
});
}
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
Reproduce el problema usando los fragmentos de TypeScript proporcionados y el enlace a Playground, comparando el comportamiento en 3.2.4, 3.3.1 y 3.4.5. Rastrea la comprobación de tipos de indexed-access genérico y de array-slice, luego añade una prueba de regresión que demuestre que el valor obtenido mediante slice sigue siendo asignable a T[K] y verifica la suite de pruebas.
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
- Bastante claro
- Aptitud para principiantes
- 52/100