Skip to content

获取只读属性

题目

实现泛型GetReadonlyKeys<T>GetReadonlyKeys<T>返回由对象 T 所有只读属性的键组成的联合类型。

例如

ts
interface Todo {
  readonly title: string;
  readonly description: string;
  completed: boolean;
}

type Keys = GetReadonlyKeys<Todo>; // expected to be "title" | "description"

解答

ts
/**
 * 思路是将T的只读键key取出来,拿到一个{key:key}的类型(其中非只读属性的值均为never)并取value(会自动过滤掉never类型的值只剩下只读key)
 * Equal取原类型和已将原类型只读属性全去掉的类型({ -readonly [R in P]: T[R] })对比结果为真的赋值never,为假说明key类型不一样,赋值key(供最后一步取key)
 * [ P in keyof Required<T> ] 生成一个新类型,该类型与 T 拥有相同的属性,但是所有属性皆为必选项,保证能取到所有key
 * 最后一步keyof Result依然会获得所有key,即使有些key对应值为never,故而用Result{keyof T}取值过滤掉never
 **/
type GetReadonlyKeys<T> = {
  [P in keyof Required<T>]: Equal<
    { [k in P]: T[k] },
    { -readonly [R in P]: T[R] }
  > extends true
    ? never
    : P;
}[keyof T];

Released under the MIT License.