TypeScriptã®Mapped Typeså®å šã¬ã€ãïŒåã®å€æãèªåšã«æãæè¡
ç§ã¯ããã°ã©ãã³ã°æŽ1幎åã«ãªããšã³ãžãã¢ã§ãæè¿ã¯Excel VBAã®é£èŒèšäºãå·çããŠããŸããããä»åã¯ããã³ããšã³ãéçºã§éèŠã«ãªãTypeScriptã®é«åºŠãªåã·ã¹ãã ã«ã€ããŠè§£èª¬ããŸããç¹ã«ãMapped TypesïŒããããã¿ã€ãïŒããšãã匷åãªæ©èœã«ã€ããŠããã®ä»çµã¿ãšå®çšçãªæŽ»çšæ¹æ³ã詳ãã説æããŠãããŸãã
Mapped Typesã¯ãæ¢åã®åããæ°ããåãçæããéã«äœ¿çšãããé«åºŠãªåæäœæè¡ã§ãTypeScriptã®åå®å šæ§ãæå€§é掻çšããããã«æ¬ ãããªãç¥èã§ããäžèŠè€éã«èŠããŸããããã®ä»çµã¿ãçè§£ããããšã§ãããæè»ã§ä¿å®æ§ã®é«ãã³ãŒããæžãããšãã§ããããã«ãªããŸãã
ç®æ¬¡
- ã¯ããã«
- Mapped Typesãšã¯
- åºæ¬çãªæ§æãšä»çµã¿
- ããŒã®æäœæè¡
- æ¡ä»¶ä»ãåãšã®çµã¿åãã
- å®çšçãªå¿çšäŸ
- çµã¿èŸŒã¿ãŠãŒãã£ãªãã£åã®ä»çµã¿
- ããã©ãŒãã³ã¹ãšå¶çŽäºé
- å®åã§ã®ãã¹ããã©ã¯ãã£ã¹
- ãŸãšã
ã¯ããã«
TypeScriptã¯ãJavaScriptãåºç€ã«ããåä»ãããµããŒãããèšèªã§ããåã·ã¹ãã ã培åºçã«æŽ»çšããããšã§ãéçºè ã¯ãã°ãæžãããã³ãŒãã®ä¿å®æ§ãé«ããããšãå¯èœã§ããããããTypeScriptãæ·±ãçè§£ããã«ã¯ãç¹ã«ãMapped TypesïŒããããã¿ã€ãïŒãã®ãããªé«åºŠãªæ©èœãæ£ããæäœããã¹ãã«ãæ±ããããŸãããã®æ©èœã«ãããæ¢åã®åãåºã«æ°ããªåãçæããåå®å šæ§ãç¶æãã€ã€æè»ãªã³ãŒããæžãããšãã§ããŸãã
å®åã§ã¯ãAPIããååŸããããŒã¿ããŠãŒã¶ãŒã€ã³ã¿ãŒãã§ãŒã¹çšã«å€æããããããŒã¿ããŒã¹ãšã³ãã£ãã£ïŒããŒã¿ããŒã¹ã«ä¿åãããŠããå®äœ[äŸ: ããŒãã«ã®1è¡ãæãã¬ã³ãŒããªã©ãããŒã¿ããŒã¹ã«ä¿åãããŠããåã ã®ããŒã¿]ïŒã®äžéšã ããå ¬éçšã«å å·¥ããå¿ èŠãçããŸãããããã®èª²é¡ã«å¯ŸããŠããMapped TypesããæŽ»çšããããšã§ãéè€ã³ãŒãã®åæžãã¡ã³ããã³ã¹æ§ã®åäžãå³ããŸãã
æ¬èšäºã§ã¯ãTypeScriptã®ãMapped Typesããšãã匷åãªåæäœæ©èœã«çŠç¹ãåœãŠããããã®èª²é¡ãå¹ççã«è§£æ±ºããæ¹æ³ã解説ããŸãã
Mapped Typesãšã¯
åºæ¬æŠå¿µ
Mapped TypesïŒãããåïŒã¯ãæ¢åã®åã®ããããã£ãå埩åŠçããŠãæ°ããåãçæããTypeScriptã®æ©èœã§ããJavaScriptã®é
åã¡ãœãã map()
ãšäŒŒãæŠå¿µã§ããåã«å¯Ÿããmapæäœããšèããããšãã§ããŸãã
åã®ãããã³ã°ãšã¯
ããã°ã©ãã³ã°ã«ãããããããã³ã°ããšã¯ãããããŒã¿æ§é ã®åèŠçŽ ã«å¯ŸããŠç¹å®ã®åŠçãé©çšããæ°ããããŒã¿æ§é ãçæããããšã§ããMapped Typesã§ã¯ãåã®ããããã£ããèŠçŽ ãã«ããããåããããã£ã«å¯ŸããŠå倿åŠçãé©çšããŠæ°ããåãçæããŸãã
ãªãMapped Typesãå¿ èŠãªã®ã
åŸæ¥ã®åå®çŸ©ã§ã¯ã䌌ããããªæ§é ã®åãè€æ°å®çŸ©ããå¿
èŠããããŸãããäŸãã°ããŠãŒã¶ãŒæ
å ±ã衚ãåãšããã®ãŠãŒã¶ãŒæ
å ±ã®æŽæ°çšã®åïŒãã¹ãŠã®ããããã£ããªãã·ã§ãã«ïŒãå¥ã
ã«å®çŸ©ããŠããŸããã
â» ãªãã·ã§ãã«ã«ã€ããŠã¯ãåŸè¿°ããŸãã
// ãŠãŒã¶ãŒæ
å ±ã衚ãå
interface User {
id: number;
name: string;
email: string;
age: number;
}
// æåã§å
šããããã£ããªãã·ã§ãã«ã«å®çŸ©
interface UserUpdate {
id?: number;
name?: string;
email?: string;
age?: number;
}
ãã®æ¹æ³ã«ã¯ä»¥äžã®åé¡ããããŸãã
- ã³ãŒãã®éè€: 䌌ããããªåå®çŸ©ãç¹°ãè¿ãæžãå¿ èŠããã
- ä¿å®æ§ã®äœäž: å ã®åã倿ŽãããŠããé¢é£ããåã¯èªåçã«æŽæ°ãããªã
- 人çãã¹ã®å¯èœæ§: æåã§åãå®çŸ©ããéã«ãããããã£ã®æŒããåã®ééããçºçãããã
Mapped Typesã䜿çšããããšã§ããããã®åé¡ãå¹ççã«è§£æ±ºã§ããŸãã
åºæ¬çãªæ§æãšä»çµã¿
åºæ¬æ§æã®è§£æ
Mapped Typesã®åºæ¬æ§æã¯ä»¥äžã®åœ¢åŒã§ãã
type MappedType<T> = {
[K in keyof T]: T[K]
}
ãã®æ§æã詳ããåè§£ããŠèª¬æããŸãã
[K in keyof T]
ã®è§£æ
ãã®éšåã¯ãã€ã³ããã¯ã¹çœ²åããšåŒã°ãã以äžã®èŠçŽ ã§æ§æãããŠããŸãã
-
K
: å倿°ïŒããããã£ããŒã衚ãïŒ -
in
: ã€ãã¬ãŒã·ã§ã³æŒç®åïŒããã®äžã®åèŠçŽ ã«å¯ŸããŠããšããæå³ïŒ -
keyof T
: åT
ã®ãã¹ãŠã®ããããã£ããŒã® Unionå(ãAãŸãã¯BãŸãã¯Cãã®ããã«è€æ°ã®å€ã®ãã¡ããããäžã€ã衚ãå)
åäœã®ä»çµã¿
-
keyof T
ã§åT
ã®ãã¹ãŠã®ããããã£ããŒãååŸ -
in
æŒç®åã§ããããã®ããŒã«å¯ŸããŠå埩åŠçãå®è¡ - åããŒ
K
ã«å¯ŸããŠ: T[K]
ã§å¯Ÿå¿ããåãæå® - çµæãšããŠæ°ããåãçæããã
å ·äœçãªåäœäŸ
以äžã®äŸã§ãMapped Typesãã©ã®ããã«åäœããããèŠãŠã¿ãŸãããã
type Person = {
name: string;
age: number;
isActive: boolean;
}
// ãã¹ãŠã®ããããã£ããªãã·ã§ãã«ã«ããMapped Type
type PartialPerson = {
[K in keyof Person]?: Person[K]
}
ãã®åŠçã¯ä»¥äžã®ã¹ãããã§å®è¡ãããŸãã
-
keyof Person
â"name" | "age" | "isActive"
- åããŒã«å¯ŸããŠå埩åŠçïŒ
-
K = "name"
ã®ãšã âname?: string
-
K = "age"
ã®ãšã âage?: number
-
K = "isActive"
ã®ãšã âisActive?: boolean
-
- æçµçãªå
type PartialPerson = { name?: string; age?: number; isActive?: boolean; }
ãªãã·ã§ãã«ããããã£ãšã¯
ãªãã·ã§ãã«ããããã£ãšã¯ããªããžã§ã¯ãã®åå®çŸ©ã«ãããŠããã£ãŠããªããŠãè¯ããããããã£ã®ããšã§ããããããã£åã®åŸã« ?
ãä»ããããšã§å®çŸ©ããããã®ããããã£ãæããªããªããžã§ã¯ãã§ãåãšã©ãŒã«ãªããŸãããäŸãã° PartialPerson
åã§ã¯ã{}
(空ã®ãªããžã§ã¯ã) ã { name: "倪é" }
(äžéšã®ããããã£ã®ã¿) ãšãã£ããªããžã§ã¯ããæå¹ã«ãªããŸãã
ããŒã®æäœæè¡
Mapped Typesã§ã¯ãããããã£ã®ããŒèªäœã倿ããããšãã§ããŸããããã«ãããããæè»ãªå倿ãå¯èœã«ãªããŸãã
ããŒã®ä¿®é£Ÿ
ãªãã·ã§ãã«ä¿®é£Ÿå
// ãã¹ãŠã®ããããã£ããªãã·ã§ãã«ã«ãã
type Optional<T> = {
[K in keyof T]?: T[K]
}
// ãã¹ãŠã®ããããã£ãå¿
é ã«ããïŒãªãã·ã§ãã«ä¿®é£Ÿåãåé€ïŒ
type Required<T> = {
[K in keyof T]-?: T[K]
}
readonly修食å
// ãã¹ãŠã®ããããã£ãèªã¿åãå°çšã«ãã
type Readonly<T> = {
readonly [K in keyof T]: T[K]
}
// èªã¿åãå°çšä¿®é£Ÿåãåé€ãã
type Mutable<T> = {
-readonly [K in keyof T]: T[K]
}
ããŒåã®å€æ
ãããã³ã°åå
ã§ as
ããŒã¯ãŒãã䜿ããšãããŒã®ååã倿ã§ããŸãã
äŸãã°ãããããã£åã«ãã¬ãã£ãã¯ã¹ã远å ããããç¹å®ã®åœåèŠåã«å€æãããããå Žåã«äŸ¿å©ã§ããTemplate Literal TypesïŒ${...}
æ§æïŒãšçµã¿åãããããšã§ãåã¬ãã«ã§ã®æååæäœãå¯èœã«ãªããŸãã
Template Literal TypesïŒãã³ãã¬ãŒããªãã©ã«åïŒ
TypeScript 4.1ã§å°å
¥ãããæ©èœã§ãJavaScriptã®ãã³ãã¬ãŒããªãã©ã«ïŒããã¯ã¯ã©ãŒãã§å²ãŸããæååïŒãšåæ§ã®æ§æãåã®äžçã§äœ¿çšã§ããŸãã${Type1}${Type2}
ã®ããã«åãçµã¿åãããŠæ°ããæåååãäœæã§ããŸããããã«ãããåã¬ãã«ã§ã®æååæäœãæååã®çµåãå¯èœã«ãªãããã衚çŸåè±ããªåå®çŸ©ãå®çŸã§ããŸãã
// ããŒåã«ãã¬ãã£ãã¯ã¹ã远å
type AddPrefix<T, Prefix extends string> = {
[K in keyof T as `${Prefix}${string & K}`]: T[K]
}
type User = {
name: string;
age: number;
}
// ãã¹ãŠã®ããŒã« "user_" ãã¬ãã£ãã¯ã¹ã远å
type UserWithPrefix = AddPrefix<User, "user_">
// çµæ: { user_name: string; user_age: number; }
extends ã®åºæ¬
TypeScriptã® extends
ããŒã¯ãŒãã¯ããã®äžçš®ã§ããããããã®æ¡ä»¶ãæºããããšããå¶çŽã衚ããŸããK extends keyof T
ãšããèšè¿°ã¯ããåãã©ã¡ãŒã¿Kã¯Tåã®ããããã£åïŒããŒïŒã®äžããéžã°ããªããã°ãªããªãããšããæå³ã§ãã
ãã®å¶çŽã«ãããååšããªãããããã£ã誀ã£ãŠæå®ããããšãé²ããåå®å
šæ§ãé«ããŠããŸãã
ããŒã®ãã£ã«ã¿ãªã³ã°
ãããã³ã°åãš conditional types
ïŒæ¡ä»¶ä»ãåïŒãçµã¿åãããããšã§ãç¹å®ã®æ¡ä»¶ã«åºã¥ããŠãªããžã§ã¯ãã®ããããã£ããã£ã«ã¿ãªã³ã°ã§ããŸããas
ç¯ã§æ¡ä»¶åŒã䜿çšããæ¡ä»¶ã«åèŽããªãããŒãnever
åã«ããããšã§ãã®ããããã£ãé€å€ããããç¹å®ã®ããŒã®ã¿ãæœåºãããã§ããŸããããã¯ãªããžã§ã¯ãåããå¿
èŠãªéšåã ããåãåºãéã«éåžžã«äŸ¿å©ãªææ³ã§ãã
type User = {
id: number;
name: string;
email: string;
password: string;
}
// ç¹å®ã®ããŒãé€å€ãã
type Omit<T, K extends keyof T> = {
[P in keyof T as P extends K ? never : P]: T[P]
}
// id ãš password ãé€å€ããåãäœæ
type PublicUser = Omit<User, 'id' | 'password'>
// çµæ: { name: string; email: string; }
// ç¹å®ã®ããŒã®ã¿ãæœåºãã
type Pick<T, K extends keyof T> = {
[P in K]: T[P]
}
// name ãš email ã®ã¿ãå«ãåãäœæ
type UserBasicInfo = Pick<User, 'name' | 'email'>
// çµæ: { name: string; email: string; }
Conditional TypesïŒæ¡ä»¶ä»ãåïŒ
TypeScriptã®æ©èœã§ãT extends U ? X : Y
ãšããäžé
æŒç®åã®ãããªæ§æã䜿ã£ãŠãæ¡ä»¶ã«åºã¥ããŠåãéžæã§ããŸãããããã³ã°åã®as
ç¯ãšçµã¿åããããšãæ¡ä»¶ã«åºã¥ããŠããŒåããã£ã«ã¿ãªã³ã°ã§ããŸããããšãã°ãP extends K ? never : P
ãšããåŒã§ã¯ãP
ãK
ã«å«ãŸããå Žåã¯never
ïŒãã®ããŒãé€å€ïŒãããã§ãªããã°å
ã®ããŒåP
ã䜿ããšããæå³ã«ãªããŸãã
æ¡ä»¶ä»ãåãšã®çµã¿åãã
åè¿°ã®ãããã³ã°åãš conditional types
ïŒæ¡ä»¶ä»ãåïŒã®çµã¿åããã§ãåã®æ§é ãä¿ã¡ãªããç¹å®ã®æ¡ä»¶ã«åºã¥ããŠããããã£ã倿ã»ãã£ã«ã¿ãªã³ã°ã§ããŸãã
åºæ¬çãªæ¡ä»¶ä»ããããã³ã°
type User = {
name: string;
age: number;
email: string;
}
// æåååã®ããããã£ã®ã¿ãæœåº
type StringPropsOnly<T> = {
[K in keyof T]: T[K] extends string ? T[K] : never
}
type StringOnlyUser = StringPropsOnly<User>;
// çµæ: { name: string; age: never; email: string; }
// 泚æ: neverã¯ããããããŸãããå®éã®ãªããžã§ã¯ãåãšããŠã¯é€å€ãããŸãã
ãã®äŸã§ã¯T[K] extends string ? T[K] : never
ãšããæ¡ä»¶åŒã§ãããã®ããããã£ã®åãæååãªãå
ã®åãä¿æããããã§ãªããã°neveråã«ããããšæå®ããŠããŸãã
ãã ããããã ãã§ã¯ããããã£ãå®å
šã«é€å€ãããããã§ã¯ãªããage: never
ã®ããã«åãnever
ã®ããããã£ãå«ãŸããåãçæãããŸãã
åã«åºã¥ã倿
type Data = {
name: string;
count: number;
isActive: boolean;
}
// ããããã£ã®åã«åºã¥ããŠç°ãªã倿ãé©çš
type Transform<T> = {
[K in keyof T]: T[K] extends string
? `String: ${T[K]}`
: T[K] extends number
? `Number: ${T[K]}`
: T[K]
}
type TransformedData = Transform<Data>;
// çµæ: {
// name: `String: ${string}`;
// count: `Number: ${number}`;
// isActive: boolean;
// }
ãã®äŸã§ã¯ããªããžã§ã¯ãå T
ã®ããããã£ã®åã«åºã¥ããŠãç°ãªãå倿ãé©çšããŸããæåååã®ããããã£ã¯ String:
ãšãããã¬ãã£ãã¯ã¹ãä»ããæååãªãã©ã«åã«å€æããæ°å€åã®ããããã£ã¯ Number:
ãšãããã¬ãã£ãã¯ã¹ãä»ããæååãªãã©ã«åã«å€æããŸãããã以å€ã®åã®ããããã£ã¯ãã®ãŸãŸã®åãä¿æããŸãã
æ¡ä»¶ä»ãåã®äœ¿çšäžã®æ³šæ
æ¡ä»¶ä»ãåãå€çšãããšåã®èšç®ãè€éã«ãªããTypeScriptã³ã³ãã€ã©ã®ããã©ãŒãã³ã¹ã«åœ±é¿ãäžããå¯èœæ§ããããŸããç¹ã«æ·±ããã¹ãããæ¡ä»¶åå²ã¯é¿ããå¯èœãªéãã·ã³ãã«ãªæ§é ãä¿ã€ããšãæšå¥šããŸãã
å®çšçãªäœ¿çšäŸ
1. APIã¬ã¹ãã³ã¹åãããã©ãŒã åãžã®å€æ
APIããååŸããããŒã¿ã®åãšããŠãŒã¶ãŒå ¥åçšã®ãã©ãŒã åã¯ç°ãªãããšãå€ãã§ãããããã³ã°åã䜿ã£ãŠãAPIåããèªåçã«ãã©ãŒã åãçæã§ããŸãããã®äŸã§ã¯ãèªã¿åãå°çšã®IDãæ¥æãã£ãŒã«ããé€å€ããæ®ãã®ãã£ãŒã«ãããªãã·ã§ãã«ã«ããŠããŸãã
// APIã¬ã¹ãã³ã¹ã®å
type ApiUser = {
readonly id: number;
name: string;
email: string;
createdAt: Date;
updatedAt: Date;
}
// ãã©ãŒã çšã®åïŒIDãšæ¥æã¯é€å€ãä»ã¯ãªãã·ã§ãã«ïŒ
type UserForm = {
[K in keyof ApiUser as K extends 'id' | 'createdAt' | 'updatedAt'
? never
: K]?: ApiUser[K]
}
// çµæ: { name?: string; email?: string; }
2. ããŒã¿ããŒã¹ãšã³ãã£ãã£ããDTOåã®çæ
ããŒã¿ããŒã¹ãšã³ãã£ãã£ã«ã¯ãã¹ã¯ãŒãããã·ã¥ãªã©ã®æ©å¯æ
å ±ãå«ãŸããããšããããŸãããå€éšAPIã«å
¬éããéã«ã¯ããããé€å€ããå¿
èŠããããŸãããããã³ã°åã䜿ã£ãŠãå®å
šã«ããŒã¿ãå
¬éããããã® DTO
ïŒData Transfer Object: å€éšãžæž¡ãããŒã¿åœ¢åŒïŒãèªåçæã§ããŸãã
// ããŒã¿ããŒã¹ãšã³ãã£ãã£
type UserEntity = {
id: number;
name: string;
email: string;
passwordHash: string;
internalNotes: string;
createdAt: Date;
updatedAt: Date;
}
// å
¬éAPIçšã®DTOïŒæ©å¯æ
å ±ãé€å€ïŒ
type UserDto = {
[K in keyof UserEntity as K extends 'passwordHash' | 'internalNotes'
? never
: K]: UserEntity[K]
}
3. åå®å šãªã€ãã³ããã³ãã©ãŒã®çæ
ã€ãã³ãé§åã¢ãŒããã¯ãã£ïŒã€ãã³ãããã£ããã«åŠçãå®è¡ãããä»çµã¿ïŒã§ã¯ãããŸããŸãªã€ãã³ããšããã«å¯Ÿå¿ãããã³ãã©ãŒããããŸãããããã³ã°åãšãã³ãã¬ãŒããªãã©ã«åãçµã¿åãããããšã§ãã€ãã³ãå®çŸ©ããåå®å šãªã€ãã³ããã³ãã©ãŒåãèªåçæã§ããŸããããã«ãããã€ãã³ãã®ããããã£å€æŽæã«é¢é£ãããã³ãã©ãŒåãèªåçã«æŽæ°ãããŸãã
// ã€ãã³ãå®çŸ©
type Events = {
userLogin: { userId: number; timestamp: Date };
userLogout: { userId: number };
pageView: { url: string; userId?: number };
}
// åå®å
šãªã€ãã³ããã³ãã©ãŒå
type EventHandlers = {
[K in keyof Events as `on${Capitalize<string & K>}`]: (data: Events[K]) => void
}
// çµæ: {
// onUserLogin: (data: { userId: number; timestamp: Date }) => void;
// onUserLogout: (data: { userId: number }) => void;
// onPageView: (data: { url: string; userId?: number }) => void;
// }
ãã®äŸã§ã¯ãã€ãã³ãåã«åºã¥ã㊠on[ã€ãã³ãå]
ãšããååã®é¢æ°ãçæããããããã®é¢æ°ã察å¿ããã€ãã³ãããŒã¿ãåŒæ°ãšããŠåãåãããã«ããŸãã
ããšãã°ãuserLogin
ãšããã€ãã³ããçºçããæã¯ onUserLogin
ãšãã { userId: number; timestamp: Date }
åã®ããŒã¿ãåãåã颿°ã«ãªããŸãã
ãã®TypeScriptã®æžãæ¹ã䜿ãããšã§ãããæ°ããã€ãã³ãã远å ããããã€ãã³ãã®å
容ãå€ãã£ãå Žåã§ãã察å¿ãããã³ãã©ãŒã®åãèªåã§æ£ããæŽæ°ãããã®ã§ãåã®å®å
šæ§ãä¿ãããŸãã(åã®æžãééãããã¹ãé²ããŸã)
Capitalize ãŠãŒãã£ãªãã£å
Capitalize<string>
ã¯TypeScriptã®çµã¿èŸŒã¿ãŠãŒãã£ãªãã£åïŒåå©çšæ§ã®é«ãå
±éåŠçãè£å©çæ©èœããŸãšããåïŒã§ãæåååã®æåã®æåã倧æåã«å€æããŸããäŸãã° Capitalize<'userLogin'>
㯠'UserLogin'
åã«ãªããŸããããã¯TypeScript 4.1ã§å°å
¥ãããæ©èœã§ãä»ã«ã Uppercase<string>
ãLowercase<string>
ãUncapitalize<string>
ãªã©ã®æååæäœçšãŠãŒãã£ãªãã£åããããŸãã
ãã®äŸã§ã¯ Capitalize<string & K>
ã䜿ã£ãŠãã€ãã³ãåã®å
é ã倧æåã«ããŠããŸããstring & K
ãšãã衚çŸã¯ãK
ãæåååã§ããããšãä¿èšŒããããã®ãã®ã§ãã
å®åã§ã®ãã¹ããã©ã¯ãã£ã¹
1. åœåèŠåã®çµ±äž
Mapped Typesã䜿çšããåã«ã¯ãäžè²«ããåœåèŠåãé©çšããŸãããã
// æšå¥šãããåœåãã¿ãŒã³
type UserPartial = Partial<User>; // æ¢åå + æäœå
容
type CreateUserDto = Omit<User, 'id'>; // çšé + æ¢åå + Dto
type UpdateUserForm = Partial<Pick<User, 'name' | 'email'>>; // çšé + æ¢åå + Form
2. åã®ææžå
è€éãªMapped Typesã«ã¯é©åãªã³ã¡ã³ããä»ããŸãããã
/**
* APIã¬ã¹ãã³ã¹ãããã©ãŒã çšã®åãçæ
* - IDãã£ãŒã«ããé€å€
* - ãã¹ãŠã®ãã£ãŒã«ãããªãã·ã§ãã«ã«å€æŽ
* - æ¥æãã£ãŒã«ããæåååã«å€æ
*/
type ApiToFormType<T extends Record<string, any>> = {
[K in keyof T as K extends 'id' ? never : K]?:
T[K] extends Date ? string : T[K]
}
3. åå©çšå¯èœãªæ±çšåã®äœæ
ãããžã§ã¯ãåºæã®å倿ãã¿ãŒã³ã¯ãåå©çšå¯èœãªæ±çšåãšããŠå®çŸ©ããŸãã
// ãããžã§ã¯ãå
±éã®ãŠãŒãã£ãªãã£å
type FormType<T> = Partial<Omit<T, 'id' | 'createdAt' | 'updatedAt'>>;
type CreateType<T> = Omit<T, 'id' | 'createdAt' | 'updatedAt'>;
type UpdateType<T> = Partial<Omit<T, 'id' | 'createdAt'>>;
ãŸãšã
TypeScriptã®Mapped Typesã¯ãåã·ã¹ãã ãæå€§éã«æŽ»çšããããã®åŒ·åãªããŒã«ã§ãããæ¢åã®åããæ°ããåãå¹ççã«çæããããšã§ãã³ãŒãã®éè€ãæžãããåã®äžè²«æ§ãšä¿å®æ§ãå€§å¹ ã«åäžãããããšãã§ããŸããåºæ¬çãªæ§æããå§ãŸããããŒã®ä¿®é£Ÿãååå€æãæ¡ä»¶ä»ãåãšã®çµã¿åãããªã©ãæ§ã ãªãã¯ããã¯ãç¿åŸããããšã§ããã衚çŸåè±ããªåå®çŸ©ãå¯èœã«ãªããŸãã
å®åã§ã¯ãAPIã¬ã¹ãã³ã¹ãããã©ãŒã åãžã®å€æãããŒã¿ããŒã¹ãšã³ãã£ãã£ããDTOã®çæãåå®å šãªã€ãã³ããã³ãã©ãŒã®å®è£ ãªã©ãå€å²ã«ãããå Žé¢ã§Mapped Typesã®æ©æµãåããããšãã§ããŸãããŸããåœåèŠåã®çµ±äžãé©åãªææžåãåå©çšå¯èœãªæ±çšåã®äœæãšãã£ããã¹ããã©ã¯ãã£ã¹ãåãå ¥ããããšã§ãããŒã å šäœã®éçºå¹çãšåå®å šæ§ãããã«é«ããããšãã§ããã§ãããã
ããèšäºã®å 容ã«ééããããã°ãã³ã¡ã³ãã§ãææããã ããŸããšå¹žãã§ãããŸããããè¯ãæ¹æ³ãä»£æ¿ææ®µããåç¥ã®æ¹ãããã£ããããŸãããããã²å ±æããŠããã ããã°ãšåããŸããäŸãã°ãããè€éãªå倿ãã¿ãŒã³ããå€§èŠæš¡ãããžã§ã¯ãã§ã®å¹æçãªåèšèšã¢ãããŒããªã©ãçæ§ã®ç¥èŠããã¹ããã©ã¯ãã£ã¹ããèããããã ããã°å¹žãã§ãã