Pick
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import { FormikHandlers } from "formik";
interface Values {
[key: string]: string;
}
interface Props {
handleChange: Pick<FormikHandlers, "handleChange">;
handleSubmit: Pick<FormikHandlers, "handleSubmit">;
handleBlur: Pick<FormikHandlers, "handleBlur">;
values: Values;
}
const CommonSearchForm = ({
handleChange,
handleSubmit,
handleBlur,
values,
}: Props) => {
console.log(handleChange);
console.log(handleSubmit);
console.log(handleBlur);
console.log(values);
return <div>CommonSearchForm</div>;
};
export default CommonSearchForm;
처음에 위 코드와 같이 formik의 FormikHandlers에서 해당 타입을 Pick을 사용하여 handleChange, handleSubmit 들의 타입을 가져오려고 했으나 사용하는 부분에서 아래와 같은 에러가 발생했다.
1
2
'handleChange' 속성이 '{ (e: ChangeEvent<any>): void; <T_1 = string | ChangeEvent<any>>(field: T_1): T_1 extends ChangeEvent<any> ? void : (e: string | ChangeEvent<any>) => void; }' 형식에 없지만 'Pick<FormikHandlers, "handleChange">' 형식에서 필수입니다.ts(2741)
types.d.ts(102, 5): 여기서는 'handleChange'이(가) 선언됩니다.
그 이유는 Pick<Type, Key>은 주어진 Type에서 Key로 속성을 선택한 새로운 타입을 반환하기 때문이다. (내가 생각을 완전 잘못했음)
해결
첫 번째 방법
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import { FormikHandlers } from "formik";
interface Props {
handleChange: FormikHandlers["handleChange"];
handleSubmit: FormikHandlers["handleSubmit"];
handleBlur: FormikHandlers["handleBlur"];
values: Values;
}
const CommonSearchForm = ({
handleChange,
handleSubmit,
handleBlur,
values,
}: Props) => {
...
return <div>...</div>
};
두 번째 방법
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import { FormikHandlers } from "formik";
interface Values {
[key: string]: string;
}
const CommonSearchForm = ({
handleChange,
handleSubmit,
handleBlur,
values,
}: Pick<FormikHandlers, "handleChange" | "handleSubmit" | "handleBlur"> & {
values: Values;
}) => {
console.log(handleChange);
console.log(handleSubmit);
console.log(handleBlur);
console.log(values);
return <div>CommonSearchForm</div>;
};
MappedType
기존에 정의되어 있던 타입을 자바스크립트의 map() API 함수처럼 새로운 타입으로 정의해주는 것이다.
1
2
3
type Subset<T> = {
[key in keyof T]?: T[key];
};
1
2
3
4
5
6
7
8
9
10
11
type Subset<T> = {
[key in keyof T]?: T[key];
};
interface Person {
age: number;
name: string;
}
const nameOnly: Subset<Person> = { name: 'Tony' };