angular / angular/angular

Support full structural subtyping/"duck typing" for typed forms

Abierto
#49,374 2 comentarios 4 reacciones 0 asignados Ver en GitHub
area: forms
Lenguaje dominante
TypeScript
Estrellas
101k
Forks
27.5k
Merge medio
1 d 19 h
PR fusionados (30 d)
288

Descripción

### Which @angular/* package(s) are relevant/related to the feature request?

forms

### Description

In TS you can take advantage of duck typing to assign objects that contain the full shape of another, for example:

```ts
value: { foo: string, bar: string };
subset: { foo: string };

subset = value;
```

This works through most generic types and classes as well (eg. a `Promise` can be used in place of a `Promise`).

However, this doesn't work (most of the time) when assigning across `FormGroup`s. This would be a useful feature for shareable/generic form components - they could take a `FormGroup` of a certain type, where some (or all) fields might be optional, but where the passing component can specify some of them.

Some examples are in this stackblitz: https://stackblitz.com/edit/angular-jgpu5s?file=src/main.ts

The error (specifically in the second example) suggests the type is forcing the assignability check in both directions regardless of which side is actually being assigned, while the two types are at least somewhat compatible (can be compared).

The only alternative at the moment is to use the least restrictive type for everything, which can add unneeded fields to the usages, and/or add unneeded and cumbersome optionality/nullability.

Wasn't sure whether to put this as a feature request or bug, since there might actually be a functional difference/design decision that I'm not understanding. Possibly (?) related to https://github.com/angular/angular/issues/47091 but that seemed a bit more specific and had some inheritence/extension complexity.

### Proposed solution

Support this:

```ts
formGroup: FormGroup<{ foo: FormControl; bar: FormControl };
formGroupSubset: FormGroup<{ foo: FormControl }>;

formGroupSubset = formGroup;
```

or at least this:

```ts
formGroup: FormGroup<{ foo: FormControl; bar: FormControl };
optionalFormGroup: FormGroup<{ foo?: FormControl, bar?: FormControl }>;

optionalFormGroup = formGroup;
```

### Alternatives considered

N/A?

Guía de contribución

Abrir la guía de contribución

Línea de trabajo

Comienza con el paquete forms de Angular y reproduce las asignaciones tipadas de FormGroup del StackBlitz enlazado. Compara los ejemplos de FormGroup completo, de subconjunto y opcional, y determina después si las asignaciones propuestas se pueden admitir sin debilitar comprobaciones de tipos no relacionadas. Se considera terminado cuando las asignaciones solicitadas pasan la comprobación de tipos tal como se describe.

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
angular, typescript
Área
frontend
Tipo de issue
Nueva funcionalidad
Dificultad
5/5
Tiempo estimado
Más de una semana
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
30/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.