type MyReadonly2<T, K = keyof T> = Omit<T, K & keyof T> & {
readonly [k in keyof T as k extends K ? k : never]: T[k]
}
Solution by wendao-liu #35174
type MyReadonly2<T, P extends keyof T> = {
readonly [K in P]: T[K];
} & {
[K in keyof T as K extends P ? never : K]: T[K];
}
Solution by ClarityOfMind #35041
type MyReadonly2<T, K extends keyof T = keyof T> = {
readonly [key in K]: T[key];
} & {
[key in keyof Omit<T, K>]: T[key];
}
Solution by dominikmatt #35009
type MyReadonly2<T, K extends keyof T> = {
readonly [P in K]: T[P]
} & {
[P in Exclude<keyof T, K>]: T[P];
};
Solution by raeyoung-kim #34997
type MyReadonly2<T, K extends keyof T = keyof T> = {
readonly [key in K]: T[key]
} & {
[key in keyof T as key extends K ? never: key]: T[key]
}
Solution by 56aiden90 #34909
type MyReadonly2<T, K extends keyof T = keyof T> ={ readonly [key in K]: T[key] } & { [R in keyof T as R extends K ? never : R]: T[R] }
Solution by floatDreamWithSong #34872
type MyReadonly2<T, K extends keyof T = keyof T> = { readonly [Key in keyof Pick<T, K>]: T[Key] } & { [Key in keyof Omit<T, K>]: T[Key] }
Solution by eunsukimme #34825
// your answers
type MyReadonly2<T, K extends keyof T = keyof T> = {
readonly [P in K]: T[P];
} & {
[P in keyof T as P extends K ? never : P]: T[P];
};
Solution by zeyuanHong0 #34774
// 你的答案
type MyOmit<T extends Record<string, any>, K> = {
[key in keyof T as key extends K ? never : key]: T[key]
}
type MyPick<T extends Record<string, any>, K> = {
[key in keyof T as key extends K ? key : never]: T[key]
}
type ToReadonly<T extends Record<string, any>> = {
readonly [key in keyof T]: T[key]
}
type IsRq<T, U> = (<P>() => P extends T ? 1 : 2) extends (<P>() => P extends U ? 1 : 2) ? true : false
type MyReadonly2<T extends Record<string, any>, K extends keyof T | undefined = undefined> = IsRq<K, undefined> extends true ? ToReadonly<T> : ToReadonly<MyPick<T, K>> & MyOmit<T, K>
Solution by softkilllengxiaoning #34734
type MyReadonly2<T, K extends keyof T = keyof T> = {
readonly [P in K]: T[P];
} & {
[P in keyof T as P extends K ? never : P]: T[P];
}
Solution by dev-jaemin #34630
type MyReadonly2<T, K extends keyof T = keyof T> =
{
readonly [key in K] : T[key]
} & {
[P in keyof T as P extends K ? never : P] : T[P]
}
// K extends keyof T = keyof T, use "=" here mean that assign K with default value keyof T
Solution by binhdv155127 #34602
type MyReadonly2<T extends Record<string, any>, K extends keyof T = keyof T> = { [P in keyof T as (P extends K ? never : P)]: T[P] } & { readonly [P in keyof T]: T[P] }
// your answers
Solution by Rustamaha #34589
type MyReadonly2<T, K extends keyof T = keyof T> = Omit<T, K> & {
readonly [U in K]: T[U]
} & Omit<T, K>
Solution by Yunjaejo #34588
type MyReadonly2<T, K extends keyof T = keyof T> = {
[P in keyof T as P extends K ? never : P]: T[P]
} & {
readonly [P in K]: T[P]
}
Solution by devshinthant #34560
//存在小问题的答案
type MyReadonly2<T, K extends keyof T> = Readonly<Pick<T, K>> & Omit<T, K>;
如果对于泛型K没有指定默认值,则泛型K为必填选项,无法跑通第一个案例,即仅存在单个T,而不存在K的情况。所以要为第二个泛型指定默认值。
//正确答案
type MyReadonly2<T, K extends keyof T = keyof T> = Readonly<Pick<T, K>> & Omit<T, K>;
Solution by wxh-cyber #34441
type MyReadonly2<T extends object, K extends keyof T = keyof T> = {
readonly [P in K]: T[P];
} & {
[P in keyof T as P extends K ? never : P]: T[P];
}
Solution by ktim816 #34431
type MyReadonly2<T, K extends keyof T = keyof T> = Omit<T, K> & { readonly [P in K]: T[P] }
Solution by rookie-luochao #34368
// your answers
type Pick<T,B extends keyof T> = {[K in B]: T[K]}
type Exclude<T, U> = T extends U ? never : T
type MyReadonly2<T, K extends keyof T= keyof T> = {readonly [E in K ]: T[E]} & Pick<T, Exclude<keyof T, K>>
Solution by felix1532 #34314
// 你的答案
readonly [A in K]: T[A] } & { [A in keyof T as A extends K ? never : A]: T[A] }
Solution by W-fitTiger #34232
type MyReadonly2<T, K extends keyof T = keyof T> = Readonly<Pick<T, K>> & Omit<T, K>
Solution by quitone #34202
T
에서 K
프로퍼티만 읽기 전용으로 설정해 새로운 오브젝트 타입을 만드는 제네릭 MyReadonly2<T, K>
를 구현하세요. K
가 주어지지 않으면 단순히 Readonly<T>
처럼 모든 프로퍼티를 읽기 전용으로 설정해야 합니다.
예시:
interface Todo {
title: string;
description: string;
completed: boolean;
}
const todo: MyReadonly2<Todo, "title" | "description"> = {
title: "Hey",
description: "foobar",
completed: false,
};
todo.title = "Hello"; // Error: cannot reassign a readonly property
todo.description = "barFoo"; // Error: cannot reassign a readonly property
todo.completed = true; // OK
type MyReadonly2<T, K> = {
[key in keyof T as key extends K ? readonly key : key]: T[key];
};
마치 이런 형태로 사용하고 싶은데, 잘 변경해보면
type MyReadonly2<T, K extends keyof T = keyof T> = {
// 기본타입 설정 아주 중요
readonly [P in K]: T[P];
} & {
[P in keyof T as P extends K ? never : P]: T[P];
};
K는 T의 key값을 받는 유니온 타입으로 변경하고, 기본값을 설정합니다. 그 이후 K에 포함된 P라는 key에 대해서 readonly를 설정하고 나머지 값들과 결합합니다.
그후 나머지 값들에 대해서 연산합니다.
/* _____________ 여기에 코드 입력 _____________ */
type MyReadonly2<T, K extends keyof T = keyof T> = {
readonly [P in K]: T[P];
} & {
[P in keyof T as P extends K ? never : P]: T[P];
};
/* _____________ 테스트 케이스 _____________ */
import type { Alike, Expect } from "@type-challenges/utils";
type cases = [
Expect<Alike<MyReadonly2<Todo1>, Readonly<Todo1>>>,
Expect<Alike<MyReadonly2<Todo1, "title" | "description">, Expected>>,
Expect<Alike<MyReadonly2<Todo2, "title" | "description">, Expected>>,
Expect<Alike<MyReadonly2<Todo2, "description">, Expected>>
];
// @ts-expect-error
type error = MyReadonly2<Todo1, "title" | "invalid">;
interface Todo1 {
title: string;
description?: string;
completed: boolean;
}
interface Todo2 {
readonly title: string;
description?: string;
completed: boolean;
}
interface Expected {
readonly title: string;
readonly description?: string;
completed: boolean;
}
Solution by adultlee #34128
type MyReadonly2<T, K extends keyof T = keyof T> =
& {
[TKey in keyof T as TKey extends K ? never : TKey]: T[TKey];
}
& {
readonly [KKey in K]: T[KKey];
};
Solution by ProvorovOleksii #34104
type MyReadonly2<T, K extends keyof T = keyof T> = {readonly [P in K]: T[P]} & {[P in keyof T as P extends K ? never : P] : T[P]}
Solution by G00syara #34036
// 第二个参数默认值为T的所有公共属性键
type MyReadonly2<T extends object, K extends keyof T = keyof T> = {
readonly [P in keyof T as P extends K ? P : never]: T[P]
} & {
[P in keyof T as P extends K ? never : P]: T[P]
}
Solution by ouzexi #33985
type MyOmit<T ,K extends keyof T> ={
[P in keyof T as P extends K ? never : P ] : T[P]
}
type MyReadonly2<T, K extends keyof T = keyof T> = {
readonly [P in K] : T[P]
} & MyOmit<T,K>
Solution by ckdwns9121 #33931
type MyReadonly2<T, K extends keyof T = keyof T> = {
readonly [P in K]: T[P]
} & Omit<T, K>
Solution by IamSmaLLR #33908
type MyReadonly2<T, K extends keyof T = keyof T> = {
readonly [P in keyof T as P extends K ? P : P]: T[P]
} & {
[P in keyof T as P extends K ? never : P] : T[P]
}
難しすぎる...が、新たな知見が2つあった
= keyof T
で解決&
で結合?できる
readonly
にしたいフィールドのみ抽出するというケースはあったkeyof T
に合致するものと合致しないもの両方をフィールドとして残しつつ、片方にだけreadonly
を宣言するのどうすれば良いのか分からなかったSolution by okabe-yuya #33900
type MyReadonly2<T, K extends keyof T = keyof T> = {
readonly [P in keyof T as P extends K ? P : P]: T[P]
} & {
[P in keyof T as P extends K ? never : P] : T[P]
}
Solution by notsecret32 #33887
type MyReadonly2<T, K extends keyof T = keyof T> = Omit<T, K> & {
readonly [Key in K]: T[Key]
}
Solution by Danny101201 #33773
type MyOmit<T,K extends keyof T> = {
[P in keyof T as P extends K ? never : P] : T[P]
}
type MyReadonly2<T, K extends keyof T = keyof T> = MyOmit<T,K> & {readonly [P in K] : T[P]}
Solution by ckdwns9121 #33730