From d15ee3f81dae176aeb40b482a1e6b10d8fd7396f Mon Sep 17 00:00:00 2001 From: june6723 Date: Tue, 16 Aug 2022 21:46:19 +0900 Subject: [PATCH 1/2] complete/week1 --- 1week/assignment/01.ts | 12 ++++++- 1week/assignment/02.ts | 27 +++++++++++++- 1week/assignment/03.ts | 5 ++- 1week/assignment/04.ts | 14 ++++++-- 1week/assignment/05.ts | 6 +++- 1week/assignment/06.ts | 16 ++++----- 1week/assignment/07.ts | 6 ++-- 1week/assignment/08.js | 81 ++++++++++++++++++++++++++++++++++++++++++ 1week/assignment/08.ts | 15 +++----- 1week/assignment/09.ts | 8 ++++- 1week/assignment/10.ts | 13 +++++++ 11 files changed, 171 insertions(+), 32 deletions(-) create mode 100644 1week/assignment/08.js diff --git a/1week/assignment/01.ts b/1week/assignment/01.ts index e2c4f63..01e83bf 100644 --- a/1week/assignment/01.ts +++ b/1week/assignment/01.ts @@ -1,7 +1,17 @@ /** * 아래의 객체들을 동일하게 선언할 수 있는 타입을 작성해주세요. */ -type Person = {}; + +type Name = string | { first: number, last: string} +type EventDate = string | Date | null + +type Person = { + name: Name; + age: string | number; + sex: string; + birth: EventDate; + death?: EventDate; +}; const personA: Person = { name: 'Alan Turing', diff --git a/1week/assignment/02.ts b/1week/assignment/02.ts index 1711bec..83821b8 100644 --- a/1week/assignment/02.ts +++ b/1week/assignment/02.ts @@ -144,6 +144,8 @@ const palette = { white: '#FFFFFF', } as const; + + const basicColors = { black: '#000000', white: '#FFFFFF', @@ -163,4 +165,27 @@ const basicColors = { navy: '#000080', }; -const YOURE_PALETTE_THEME = {}; +type ValueOf = T[keyof T]; + +type PaletteTheme = { + [key in keyof typeof basicColors]: ValueOf; +} + +const YOURE_PALETTE_THEME: PaletteTheme = { + black: '#00008B', + white: '#006400', + red: '#FFFAF0', + lime: '#00FF00', + blue: '#0000FF', + yellow: '#FFFF00', + 'cyan/aqua': '#483D8B', + 'magenta/fuchsia': '#FF00FF', + silver: '#C0C0C0', + gray: '#808080', + maroon: '#800000', + olive: '#F0FFF0', + green: '#008000', + purple: '#FFE4E1', + teal:'#F0E68C', + navy: '#F08080', +}; diff --git a/1week/assignment/03.ts b/1week/assignment/03.ts index 62b4cc2..c5d328f 100644 --- a/1week/assignment/03.ts +++ b/1week/assignment/03.ts @@ -1,9 +1,12 @@ /** * 아래의 userRole이 가진 리터럴 타입을 제거하여 UserInformation을 유연하게 만드려면 어떻게 할까요? */ + +type UserRole = 'normal' | 'vip' | 'admin' + type UserInformation = { userId: string; userName: string; - userRole: 'normal' | 'vip' | 'admin'; + userRole: UserRole; password: string; }; diff --git a/1week/assignment/04.ts b/1week/assignment/04.ts index c42aed8..06b0a44 100644 --- a/1week/assignment/04.ts +++ b/1week/assignment/04.ts @@ -5,14 +5,22 @@ * - 특정 index의 원소를 변경하는 update 메서드를 만들어주세요. */ -class List { - private items: any[] = []; +class List { + private items: T[] = []; - add(item: any) { + add(item: T) { this.items.push(item); } get(index: number) { return this.items[index]; } + + remove(index: number) { + return this.items.splice(index, 1); + } + + update(index: number, value: T) { + return this.items[index] = value; + } } diff --git a/1week/assignment/05.ts b/1week/assignment/05.ts index 8187dbe..03335f6 100644 --- a/1week/assignment/05.ts +++ b/1week/assignment/05.ts @@ -16,7 +16,11 @@ type HumanProps = { }; }; -const Bob: HumanProps = { +type DeepReadonly = { + readonly [key in keyof T]: DeepReadonly +} + +const Bob: DeepReadonly = { firstName: 'Bob', surname: 'Keel', profile: { diff --git a/1week/assignment/06.ts b/1week/assignment/06.ts index 4ea6939..3b666bf 100644 --- a/1week/assignment/06.ts +++ b/1week/assignment/06.ts @@ -2,22 +2,18 @@ * 아래의 코드 중 타입 별칭을 제거하여 동일한 결과를 내도록 작성해주세요. */ -type SavingAction = { - type: 'saving'; - payload: string[]; +type ActionType = 'saved' | 'saving' +type Action = { + type: ActionType, + payload?: string[] }; -const savingAction: SavingAction = { +const savingAction: Action = { type: 'saving', payload: ['Apple', 'Banana', 'Strawberry'], }; -type SavedAction = { - type: 'saved'; -}; - -const savedAction: SavedAction = { +const savedAction: Action = { type: 'saved', }; -type Actions = SavingAction | SavedAction; diff --git a/1week/assignment/07.ts b/1week/assignment/07.ts index ae02b83..f46febd 100644 --- a/1week/assignment/07.ts +++ b/1week/assignment/07.ts @@ -2,9 +2,9 @@ * 아래의 코드 중 Cylinder 타입을 유지하기 위한 코드를 작성해주세요. */ -interface Cylinder { - radius: number; - height: number; +class Cylinder { + radius = 1; + height = 1; } function calculateVolumne(shape: unknown) { diff --git a/1week/assignment/08.js b/1week/assignment/08.js new file mode 100644 index 0000000..09082f1 --- /dev/null +++ b/1week/assignment/08.js @@ -0,0 +1,81 @@ +/** + * 아래의 함수가 동작하도록 리팩토링 해주세요. + * - 문자열 배열을 입력하면 2차원 배열로 각 아이템이 p 태그로 묶여서 나옵니다. + * [ + [ + '

모두 잠드는 밤에

', + '

혼자 우두커니 앉아

', + '

다 지나버린 오늘을

', + '

보내지 못하고서 깨어있어

', + '

누굴 기다리나

', + '

아직 할 일이 남아 있었던가

', + '

그것도 아니면 돌아가고 싶은

', + '

그리운 자리를 떠올리나

', + '

무릎을 베고 누우면 나 아주 어릴 적

', + '

그랬던 것처럼 머리칼을 넘겨줘요

', + '

그 좋은 손길에 까무룩 잠이 들어도

', + '

잠시만 그대로 두어요

', + '

깨우지 말아요 아주 깊은 잠을 잘 거예요

', + '

조용하던 두 눈을

', + '

다시 나에게 내리면

', + '

나 그때처럼 말갛게

', + '

웃어 보일 수 있을까

', + '

나 지친 것 같아

', + '

이 정도면 오래 버틴 것 같아

', + '

그대 있는 곳에 돌아갈 수 있는

', + '

지름길이 있다면 좋겠어

', + '

무릎을 베고 누우면 나 아주 어릴 적

', + '

그랬던 것처럼 머리칼을 넘겨줘요

', + '

그 좋은 손길에 까무룩 잠이 들어도

', + '

잠시만 그대로 두어요

', + '

깨우지 말아요 아주 깊은 잠을 잘 거예요

', + '

스르르르륵 스르르 깊은 잠을 잘 거예요

', + '

스르르르륵 스르르 깊은 잠을

' + ] + ] + * - 함수를 리팩토링해주세요. + */ +function parseTaggedText(lines) { + var paragraphs = []; + var currPara = []; + var addParagraph = function (text) { + currPara.push("

" + text + "

"); + }; + for (var _i = 0, lines_1 = lines; _i < lines_1.length; _i++) { + var line = lines_1[_i]; + addParagraph(line); + } + paragraphs.push(currPara); + return paragraphs; +} +var parameter = [ + '모두 잠드는 밤에', + '혼자 우두커니 앉아', + '다 지나버린 오늘을', + '보내지 못하고서 깨어있어', + '누굴 기다리나', + '아직 할 일이 남아 있었던가', + '그것도 아니면 돌아가고 싶은', + '그리운 자리를 떠올리나', + '무릎을 베고 누우면 나 아주 어릴 적', + '그랬던 것처럼 머리칼을 넘겨줘요', + '그 좋은 손길에 까무룩 잠이 들어도', + '잠시만 그대로 두어요', + '깨우지 말아요 아주 깊은 잠을 잘 거예요', + '조용하던 두 눈을', + '다시 나에게 내리면', + '나 그때처럼 말갛게', + '웃어 보일 수 있을까', + '나 지친 것 같아', + '이 정도면 오래 버틴 것 같아', + '그대 있는 곳에 돌아갈 수 있는', + '지름길이 있다면 좋겠어', + '무릎을 베고 누우면 나 아주 어릴 적', + '그랬던 것처럼 머리칼을 넘겨줘요', + '그 좋은 손길에 까무룩 잠이 들어도', + '잠시만 그대로 두어요', + '깨우지 말아요 아주 깊은 잠을 잘 거예요', + '스르르르륵 스르르 깊은 잠을 잘 거예요', + '스르르르륵 스르르 깊은 잠을', +]; +console.log(parseTaggedText(parameter)); diff --git a/1week/assignment/08.ts b/1week/assignment/08.ts index 6b954fe..efb5a46 100644 --- a/1week/assignment/08.ts +++ b/1week/assignment/08.ts @@ -40,22 +40,15 @@ function parseTaggedText(lines: string[]): string[][] { const paragraphs: string[][] = []; const currPara: string[] = []; - const addParagraph = () => { - if (currPara.length) { - paragraphs.push(currPara); - currPara.length = 0; // Clear the lines - } + const addParagraph = (text: string) => { + currPara.push(`

${text}

`) }; for (const line of lines) { - if (!line) { - addParagraph(); - } else { - currPara.push(`

${line}

`); - } + addParagraph(line); } - addParagraph(); + paragraphs.push(currPara) return paragraphs; } diff --git a/1week/assignment/09.ts b/1week/assignment/09.ts index 8f4734c..582b706 100644 --- a/1week/assignment/09.ts +++ b/1week/assignment/09.ts @@ -2,7 +2,13 @@ * 아래의 함수가 정상적으로 동작하기 위해 어떤 타입을 활용하면 될까요? */ -function prettyPrint(x: any): string { +type Parameter = string | number | { + x: Parameter; + length: number; + mop: (callback: (x: Parameter)=> string) => string[] +} + +function prettyPrint(x: Parameter): string { if (typeof x === 'string') return `"${x}"`; if (typeof x === 'number') return String(x); diff --git a/1week/assignment/10.ts b/1week/assignment/10.ts index 4bd48be..cd98c44 100644 --- a/1week/assignment/10.ts +++ b/1week/assignment/10.ts @@ -1,3 +1,16 @@ /** * never, unknown, any 타입에 대해 정리하여 최대한 상세하게 적어주세요. */ + +const never = ` + TS에서 가질 수 있는 가장 작은 집합 +`; + +const unknown = ` + 모든 타입을 할당 받을 수 있으나 any와 다른 것은 unknown 타입으로 선언된 변수는 any를 제외한 다른 타입으로 선언된 변수에 할당될 수 없다는 것 +` + +const any = ` + 모든 타입을 할당 받을 수 있는 TS의 치트키. + 하지만 JS프로젝트를 TS로 마이그레이션 할때만 사용하도록 하고 실제 협업에서는 사용을 지양하자. +` From 591cdab6ab2c73ee36b7b01fbad37b4bb5c1f510 Mon Sep 17 00:00:00 2001 From: siny Date: Fri, 26 Aug 2022 13:34:12 +0900 Subject: [PATCH 2/2] =?UTF-8?q?:sparkles:=204=EC=9E=A5=20=EA=B3=BC?= =?UTF-8?q?=EC=A0=9C=20=EC=A0=9C=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 2week/assignment/01.ts | 43 ++++++++++++++++++++++++ 3week/assignment/01.ts | 25 ++++++++++++++ 3week/assignment/02.ts | 34 +++++++++++++++++++ 3week/assignment/03.ts | 40 ++++++++++++++++++++++ 3week/assignment/04.ts | 76 ++++++++++++++++++++++++++++++++++++++++++ 3week/assignment/05.ts | 33 ++++++++++++++++++ 6 files changed, 251 insertions(+) create mode 100644 3week/assignment/01.ts create mode 100644 3week/assignment/02.ts create mode 100644 3week/assignment/03.ts create mode 100644 3week/assignment/04.ts create mode 100644 3week/assignment/05.ts diff --git a/2week/assignment/01.ts b/2week/assignment/01.ts index 343b004..c679469 100644 --- a/2week/assignment/01.ts +++ b/2week/assignment/01.ts @@ -5,3 +5,46 @@ const person = { country: 'ko', sex: 'male', }; + + +type arr1 = ['a', 'b', 'c'] +type arr2 = [1, 2, 3] + +// type Arr = T; +// type First = T extends Arr ? A : any; + +// type First = T[0] // 가능 +// never[] <-- 진정한 빈 배열 +// type First = T extends never[] ? never : T[0]; +type First = T extends [infer F, ...unknown[]] ? F : never + +type head1 = First; +type head2 = First; + +type Last = T extends [...unknown[], infer L] ? L : never + +type tail1 = Last; +type tail2 = Last; + + + + +type Fn = (...args:A) => any; +type FnArgs = T extends Fn ? A : any; + +function test(name: number) { + // 값 공간 + return 3 +} +type TestFn = FnArgs; + + +type StrFn = (input: string) => string; +const getSHA: StrFn = (input: string) => { + return input; +}; + +type PromiseFn = T extends (...args: infer A) => infer R ? (...args: A) => Promise : T; +const getSHAAsync: PromiseFn = (input: string) =>{ + return new Promise((res) => input); +} diff --git a/3week/assignment/01.ts b/3week/assignment/01.ts new file mode 100644 index 0000000..364c66a --- /dev/null +++ b/3week/assignment/01.ts @@ -0,0 +1,25 @@ +/** + * 문제1 + * 다음의 파파고 번역 api 명세를 확인하고 + * 파라미터에 필요한 source 와 target 을 좁혀주세요. + * @description: 링크: https://developers.naver.com/docs/papago/papago-nmt-api-reference.md + * */ + +type SupportedLanguague = +|'ko' +|'en' +|'ja' +|'zh-CN' +|'zh-TW' +|'vi' +|'id' +|'th' +|'de' +|'ru' +|'es' +|'it' +|'fr'; + + +type PapagoParamsSource = SupportedLanguague; +type PapagoParamsTarget = SupportedLanguague; diff --git a/3week/assignment/02.ts b/3week/assignment/02.ts new file mode 100644 index 0000000..9a77018 --- /dev/null +++ b/3week/assignment/02.ts @@ -0,0 +1,34 @@ +/** + * 문제2 + * 위의 PapagoParamsSource와 PapagoParamsTarget 를 조합하여 명세에서 언급하는 + * "번역할 수 있는 원본 언어와 목적 언어는 다음과 같습니다." 의 제약조건을 참고하여 PapagoParams 인터페이스를 개선해 주세요. + * */ + +interface KoParams { + source: 'ko'; + target: SupportedLanguague; + text: string; +} +interface EnParams { + source: 'en'; + target: 'ja'|'fr'|'zh-CN'|'zh-TW'|'ko'; + text: string; +} +interface JaParams { + source: 'ja'; + target: 'zh-CN' | 'zh-TW' | 'ko'; + text: string; +} +interface ZhCnParams { + source: 'zh-Cn'; + target: 'zh-TW'; + text: string; +} + +type PapagoParams = KoParams | EnParams | JaParams | ZhCnParams; + +const params: PapagoParams= { + source: 'en', + target: 'ja', + text: 'Hello Typescript!' +} diff --git a/3week/assignment/03.ts b/3week/assignment/03.ts new file mode 100644 index 0000000..b468a17 --- /dev/null +++ b/3week/assignment/03.ts @@ -0,0 +1,40 @@ +/** + * 문제3 + * 스탑워치 구현을 보고 ui 상태 interface 설계를 개선해주세요. + * https://online-stopwatch.ko.downloadastro.com/tools/ + * */ + +// 예시 인터페이스이고, 본인이 생각하는 더 나은 인터페이스로 바꾸셔도 됩니다. +interface TimeInfo { + lappedTimeList?: string[]; + timeFormStart: string; + timeFormLastLap: string; +} +interface ButtonStyle { + color: string; + icon: string +} + +interface Initalized extends TimeInfo { + type: 'initialized'; + startButton: ButtonStyle; +} +interface Running extends TimeInfo { + type: 'running'; + pauseButton: ButtonStyle; + addLapButton: ButtonStyle; +} +interface Paused extends TimeInfo { + type: 'paused'; + startButton: ButtonStyle; + resetButton: ButtonStyle; +} +type StopWatchState = Initalized | Running | Paused; + +const initialState: StopWatchState = { + type: 'initialized', + startButton: { color: 'awf', icon: 'waef' }, + timeFormStart: '0:00', + timeFormLastLap: '0:00', + lappedTimeList: [] +} diff --git a/3week/assignment/04.ts b/3week/assignment/04.ts new file mode 100644 index 0000000..4e39040 --- /dev/null +++ b/3week/assignment/04.ts @@ -0,0 +1,76 @@ +/** + * 문제4 + * 요구사항: naver나 kakao 로그인(Oauth2.0)하기 기능 이용해 + * 유저의 이름, 닉네임, 프로필 사진을 얻어와 출력하려고 합니다. + * + * 카카오 사용자 정보 가져오기 api 명세세 + * https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api#req-user-info + * 카카오 profile 객체 스키마 + * https://developers.kakao.com/docs/latest/ko/kakaologin/rest-api#profile + * + * 네이버 프로필 API 호출하기 명세 + * https://developers.naver.com/docs/login/devguide/devguide.md#3-4-5-%EC%A0%91%EA%B7%BC-%ED%86%A0%ED%81%B0%EC%9D%84-%EC%9D%B4%EC%9A%A9%ED%95%98%EC%97%AC-%ED%94%84%EB%A1%9C%ED%95%84-api-%ED%98%B8%EC%B6%9C%ED%95%98%EA%B8%B0 + * + * 위의 명세를 참고하여 다음과 같은 타입을 정의했습니다. + * */ + +interface KakaoUserProfile { + nickname: string; + profile_image_url: string; +} + +interface KakaoUser { + name: string; + profile: KakaoUserProfile; +} + +interface NaverUser { + nickname: string; + name: string; + profile_image: string; +} +interface UserInfo { + name: string; + nickname: string; + profileImage: string; +} + +declare function getUser(userId: string): NaverUser | KakaoUser; + +const isKakaoUser = (user: NaverUser | KakaoUser): user is KakaoUser => { + return 'profile' in user; +} + +const getUserInfo = (userId: string): UserInfo => { + const userInfo: UserInfo = { + name: '', + nickname: '', + profileImage: '', + } + const response = getUser(userId); + if (isKakaoUser(response)) { + const { name, profile: { nickname, profile_image_url }} = response + userInfo.name = name; + userInfo.nickname = nickname; + userInfo.profileImage = profile_image_url; + } else { + const { nickname, name, profile_image } = response + userInfo.name = name; + userInfo.nickname = nickname; + userInfo.profileImage = profile_image; + } + return userInfo +} + +// 다음 오류를 해결하기위해 할 수 있는 모든 대안을 적용해주세요. +function renderUserProfile(userId: string) { + const app = document.querySelector('#app')!; + const user = getUserInfo(userId); + app.innerHTML = ` +
+ 이름: ${user.name} + 닉네임: ${user.nickname} + +
+ `; +} diff --git a/3week/assignment/05.ts b/3week/assignment/05.ts new file mode 100644 index 0000000..6f70ee6 --- /dev/null +++ b/3week/assignment/05.ts @@ -0,0 +1,33 @@ +/** + * 문제5 + * 회원가입 form을 만들어야합니다. + * 아이디, 비밀번호, 비밀번호 확인 text input + * 추가 정보입력 checkbox + * (추가정보입력을 체크하면) + * 주소, 전화번호 text input 을 구현하려고 합니다. + * 타입을 좀 더 좁게 관리할 수 있도록 개선해주세요. + * */ +interface AdditionalInfo { + address: string; + phone: string; +} + +interface BaseData { + id: string; + password: string; + confirmPassword: string; +} +interface SignUpData extends BaseData { + additionalInfo?: AdditionalInfo +} + +declare function postSignUpToV1(signupForm: SignUpData): void; +declare function postSignUpToV2(signupForm: SignUpData): void; + +const sendSignup = (formData: SignUpData) => { + if (formData.additionalInfo) { + postSignUpToV2(formData); + } else { + postSignUpToV1(formData); + } +};