microsoft / microsoft/TypeScript

Regression: Type T[K] as an array when sliced loses its type

Abierto
#31,549 3 comentarios 3 reacciones 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

Bug Domain: Indexed Access Types Needs Human Review
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:

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

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. 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

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.