Open yunliuyan opened 1 year ago
遍历对象key值,若对应的属性继承了Readonly则取当前值。
type GetReadonlyKeys<T> = {
[key in keyof T ]-?: Equal<Pick<T, key>, Readonly<Pick<T, key>>> extends true ? key : never
}[keyof T];
export type ExtremeReadOnly<T> = {
[K in keyof T]-?: (<U>() => U extends { -readonly [P in K]: T[K] } ? 1 : 2) extends <U>() => U extends { [P in K]: T[K] } ? 1 : 2 ? never : K;
}[keyof T];
interface ExtremeReadonlyType {
readonly name: string;
address: boolean;
readonly meta: {
description: string;
};
description: string;
}
type extremeReadonlyTest = ExtremeReadOnly<ExtremeReadonlyType>;
const extremeReadonlyTest1: extremeReadonlyTest = "name"; // Ok
const extremeReadonlyTest2: extremeReadonlyTest = "address"; // Error: Type '"description"' is not assignable to type 'extremeReadonlyTest'.ts(2322)
const extremeReadonlyTest3: extremeReadonlyTest = "meta"; // Ok
const extremeReadonlyTest4: extremeReadonlyTest = "description"; // Error: Type '"description"' is not assignable to type 'extremeReadonlyTest'.ts(2322)
type Equal<X, Y> = (
type GetReadonlyKeys
}
interface Todo { readonly title: string readonly description: string completed: boolean }
type Keys = GetReadonlyKeys
const test: Keys = 'title';
type GetReadonlyKeys<T> = {
[P in keyof T as Equal<Pick<T, P>, Readonly<Pick<T, P>>> extends true ? P: never]: T[P]
}[keyof T];
type Equals<X, Y> =
(<T>() => (T extends X ? 1 : 2)) extends
(<Z>() => (Z extends Y ? 1 : 2))
? true
: false;
// https://juejin.cn/post/7078208046283014158
type GetReadonlyKeys<T> = { [key in keyof T]: Equals<Pick<T, key>, Readonly<Pick<T, key>>> extends true ? key : never }[keyof T]
interface Todo6 {
readonly title: string
readonly description: string
completed: boolean
}
type Keys = GetReadonlyKeys<Todo6> // expected to be "title" | "description"
获取只读字段
实现泛型
GetReadonlyKeys<T>
,GetReadonlyKeys<T>
返回由对象 T 所有只读属性的键组成的联合类型。例如
测试案例: