00008-medium-readonly-2

Back

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를 설정하고 나머지 값들과 결합합니다.

그후 나머지 값들에 대해서 연산합니다.

Solution

/* _____________ 여기에 코드 입력 _____________ */

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つあった

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