타이핑된 양식을 좀 더 일관되게 만들기

9990 단어 angular
Angular 형식의 형식은 매우 훌륭합니다. 양식을 강력하게 입력하면 많은 이점이 있지만 한 가지 문제는 입력된 양식을 만들고 양식 값을 유추할 수 있는 단일 인터페이스를 정의할 수 있다는 점입니다.

다음 코드를 고려하십시오.

interface UserFormControls {
  firstName: FormControl<string>;
  lastName: FormControl<string>;
  email: FormControl<string | null>;
  age: FormControl<number | null>;
}

interface User {
  firstName: string;
  lastName: string;
  email: string | null;
  age: number | null;
}

function processUser(user: User): void {
    // ...
}

const userForm = new FormGroup<UserFormControls>({
    firstName: new FormControl('foo', { nonNullable: true }),
    lastName: new FormControl('bar', { nonNullable: true }),
    email: new FormControl('[email protected]', { nonNullable: true }),
    age: new FormControl(null)
});

processUser(userForm.value); // This won't actually compile, keep reading


이상적으로는 동일한 것을 정의하는 두 개의 개별 인터페이스를 유지하도록 강요받고 싶지 않습니다. 사용자 인터페이스는 UserFormControls에서 유추할 수 있으므로 그렇게 합시다. 이를 위해 두 가지 새로운 유형을 사용합니다.

type FormValue<T extends AbstractControl> = 
    T extends AbstractControl<infer TValue, any>
    ? TValue
    : never;
type FormRawValue<T extends AbstractControl> = 
    T extends AbstractControl<any, infer TRawValue> 
    ? TRawValue 
    : never;


이것을 UserFormControls 에 적용하면 어떤 일이 발생하는지 봅시다.

interface UserFormControls {
    firstName: FormControl<string>;
    lastName: FormControl<string>;
    email: FormControl<string | null>;
    age: FormControl<number | null>;
}
type UserForm = FormGroup<UserFormControls>;
type User = FormValue<UserForm>;
// type User = {
//  firstName?: string | undefined;
//  lastName?: string | undefined;
//  email?: string | null | undefined;
//  age?: number | null | undefined;
// }

type UserRaw = FormRawValue<UserForm>;
// type UserRaw = {
//  firstName: string;
//  lastName: string;
//  email: string | null;
//  age: number | null;
// }

User 유형에는 이제 모든 속성이 선택 사항으로 포함되어 있습니다. 이는 컨트롤을 비활성화할 수 있고 최종 양식 값에 표시되지 않기 때문입니다. 원시 값은 이전에 사용자 인터페이스를 지정한 방식으로 정확하게 입력됩니다. 첫 번째 코드 블록의 processUser(userForm.value);가 컴파일되지 않는 이유이기도 합니다.

선택하세요



여기에서 선택해야 합니다.
  • FormValue<..>를 사용하고 잠재적인 모든 속성undefined을 처리하거나,
  • FormRawValue<..>는 주의하여 사용하십시오. 비활성화할 수 있는 모든 컨트롤이 선택 사항으로 표시되어 있으면 타이핑이 제대로 됩니다.

  • 나의 추천은 후자일 것이다. 이 경우 다음 솔루션으로 끝납니다.

    type User = FormRawValue<UserForm>;
    // type User = {
    //  firstName: string;
    //  lastName: string;
    //  email: string | null;
    //  age: number | null;
    // }
    
    // ...
    
    function processUser(user: User): void {
        // ...
    }
    
    processUser(userForm.value as User);
    // or:
    processUser(userForm.getRawValue());
    


    행운을 빕니다!

    좋은 웹페이지 즐겨찾기