「重学TS 2.0 」TS 练习题第二十四题
实现一个 Mutable 工具类型,用于移除对象类型上所有属性或部分属性的 readonly 修饰符。具体的使用示例如下所示:
type Foo = {
readonly a: number;
readonly b: string;
readonly c: boolean;
};
type Mutable<T, Keys extends keyof T = keyof T> = // 你的实现代码
const mutableFoo: Mutable<Foo, 'a'> = { a: 1, b: '2', c: true };
mutableFoo.a = 3; // OK
mutableFoo.b = '6'; // Cannot assign to 'b' because it is a read-only property.
请在下面评论你的答案。
type Foo = {
readonly a: number;
readonly b: string;
readonly c: boolean;
};
type Mutable<T, Keys extends keyof T = keyof T> = {
-readonly [K in Keys]: T[K];
} &
Pick<T, Exclude<keyof T, Keys>>;
const mutableFoo: Mutable<Foo, 'a'> = { a: 1, b: '2', c: true };
mutableFoo.a = 3; // OK
mutableFoo.b = '6'; // Cannot assign to 'b' because it is a read-only property.
type Foo = {
readonly a: number;
readonly b: string;
readonly c: boolean;
};
type Mutable<T, Keys extends keyof T = keyof T> = {- readonly [K in Keys]: T[K] } & Omit<T,Keys>; // 你的实现代码
const mutableFoo: Mutable<Foo, 'a'> = { a: 1, b: '2', c: true };
mutableFoo.a = 3; // OK
// @ts-expect-error
mutableFoo.b = '6'; // Cannot assign to 'b' because it is a read-only property.
ype Foo = {
readonly a: number;
readonly b: string;
readonly c: boolean;
};
type RemoveReadonly<T, Keys extends keyof T> = {
-readonly [K in Keys]: T[K];
};
type Mutable<T, Keys extends keyof T = keyof T> = Omit<T, Keys> & RemoveReadonly<T, Keys>;
const mutableFoo: Mutable<Foo, "a"> = { a: 1, b: "2", c: true };
mutableFoo.a = 3; // OK
mutableFoo.b = "6"; // Cannot assign to 'b' because it is a read-only property.
type Foo = {
readonly a: number;
readonly b: string;
readonly c: boolean;
};
type Mutable<T, Keys extends keyof T = keyof T> = {
-readonly [K in Keys]: T[K]
} & Omit<T, Keys>
const mutableFoo: Mutable<Foo, 'a'> = { a: 1, b: '2', c: true };
mutableFoo.a = 3; // OK
mutableFoo.b = '6'; // Cannot assign to 'b' because it is a read-only property.
mutableFoo.c = '6'; // Cannot assign to 'c' because it is a read-only property.
const mutableFoo2: Mutable<Foo, 'a' | 'b'> = { a: 1, b: '2', c: true };
mutableFoo2.a = 3; // OK
mutableFoo2.b = '6'; // OK
mutableFoo2.c = '6'; // Cannot assign to 'c' because it is a read-only property.
type Foo = {
readonly a: number;
readonly b: string;
readonly c: boolean;
};
type Readonlys<T, Keys extends keyof T> = {
- readonly [p in Keys]: T[p]
}
type Mutable<T, Keys extends keyof T = keyof T> = Omit<T, Keys> & Readonlys<T, Keys>// 你的实现代码
const mutableFoo: Mutable<Foo, 'a'> = { a: 1, b: '2', c: true };
mutableFoo.a = 3; // OK
mutableFoo.b = '6'; // Cannot assign to 'b' because it is a read-only property.
// 实现一个 Mutable 工具类型,用于移除对象类型上所有属性或部分属性的 readonly 修饰符。具体的使用示例如下所示:
type Foo = {
readonly a: number;
readonly b: string;
readonly c: boolean;
};
type Mutable<T, Keys extends keyof T = keyof T> = Omit<T, Keys> & {
-readonly[k in Keys]: T[k];
};
const mutableFoo: Mutable<Foo, 'a'> = { a: 1, b: '2', c: true };
mutableFoo.a = 3; // OK
mutableFoo.b = '6'; // Cannot assign to 'b' because it is a read-only property.
知识点 -readonly 可以去除属性上的 readonly属性,语法和 -? 去掉可选属性一直。之后利用 Omit先构造一个不包含指定属性的类型,之后再基于Keys从已有的T上提取类型,通过 -readonly 去除只读限制,之后通过交叉 & 来合并二者。
type Foo = {
readonly a: number;
readonly b: string;
readonly c: boolean;
};
type Mutable<T, Keys extends keyof T = keyof T> = {
[K in keyof T as K extends Keys ? never : K]: T[K]
} & {
-readonly [K in keyof Pick<T, Keys>]: T[K]
}
const mutableFoo: Mutable<Foo, 'a'> = { a: 1, b: '2', c: true };
mutableFoo.a = 3; // OK
mutableFoo.b = '6'; // Cannot assign to 'b' because it is a read-only property.
type Foo = {
readonly a: number;
readonly b: string;
readonly c: boolean;
};
type Mutable<T, Keys extends keyof T = keyof T> = {
-readonly[ k in Keys]: T[k]
} & Omit<T, Keys> // 你的实现代码
const mutableFoo: Mutable<Foo, 'a'> = { a: 1, b: '2', c: true };
mutableFoo.a = 3; // OK
mutableFoo.b = '6'; // Cannot assign to 'b' because it is a read-only property.
export default {}
// 实现一个 Mutable 工具类型,用于移除对象类型上所有属性或部分属性的 readonly 修饰符。具体的使用示例如下所示: type Foo = { readonly a: number; readonly b: string; readonly c: boolean; };
type Mutable<T, Keys extends keyof T = keyof T> = { -readonly [P in Keys]: T[P] } & Omit<T, Keys>
type a = Readonly<Omit<Foo, 'a'>>
const mutableFoo: Mutable<Foo, 'a'> = { a: 1, b: '2', c: true };
mutableFoo.a = 3; // OK // mutableFoo.b = '6'; // Cannot assign to 'b' because it is a read-only property.
type Foo = {
readonly a: number;
readonly b: string;
readonly c: boolean;
};
type NotReadonly<T> = {
-readonly [K in keyof T]: T[K]
}
type Mutable<T, Keys extends keyof T = keyof T> = NotReadonly<Pick<T, Keys>> & Omit<T, Keys>
// test
const mutableFoo: Mutable<Foo, 'a'> = { a: 1, b: '2', c: true };
mutableFoo.a = 3
mutableFoo.b = '6'
平安已经收到你的邮件啦
type Foo = {
readonly a: number;
readonly b: string;
readonly c: boolean;
};
type Mutable<T, Keys extends keyof T = keyof T> = Omit<T, Keys> & { -readonly [k in Keys]: T[k] };
const mutableFoo: Mutable<Foo, 'a'> = { a: 1, b: '2', c: true };
mutableFoo.a = 3; // OK
mutableFoo.b = '6'; // Cannot assign to 'b' because it is a read-only property.
type Foo24 = { readonly a: number; readonly b: string; readonly c: boolean; };
type Mutable<T, Keys extends keyof T = keyof T> = Omit<T , Keys> & {
- readonly [ K in keyof Pick<T, Keys>] : T [K] }
const mutableFoo: Mutable<Foo24, 'a'> = { a: 1, b: '2', c: true };
mutableFoo.a = 3; // OK mutableFoo.b = '6'; // Cannot assign to 'b' because it is a read-only property. mutableFoo.c = false; //Cannot assign to 'b' because it is a read-only property.
type Foo = {
readonly a: number;
readonly b: string;
readonly c: boolean;
};
const mutableFoo: Mutable<Foo, 'a'> = { a: 1, b: '2', c: true };
mutableFoo.a = 3; // OK
mutableFoo.b = '6'; // Cannot assign to 'b' because it is a read-only property.
type Mutable<T, Keys extends keyof T = keyof T> =
{
-readonly [K in Keys]: T[K]
} & Omit<T, Keys>
// 解法1: 使用原来的, 再拼上去掉readonly的特定key
type Mutable<T, Keys extends keyof T = keyof T> = {
[J in keyof T]: T[J]
} & {
-readonly [K in Keys]: T[K]
}
// 解法2: 更优解, 去掉需要去掉readonly的key
type Mutable1<T, Keys extends keyof T = keyof T> = Omit<T, Keys> & {
-readonly [K in Keys]: T[K]
}
type Foo = { readonly a: number; readonly b: string; readonly c: boolean; }; type RemoveReadonly<T extends object>={ -readonly [K in keyof T]: T[K] } type Mutable<T, Keys extends keyof T = keyof T> = Omit<T,Keys> & RemoveReadonly<Pick<T,Keys>>
const mutableFoo: Mutable<Foo, 'a'> = { a: 1, b: '2', c: true };
mutableFoo.a = 3; // OK mutableFoo.b = '6'; // Cannot assign to 'b' because it is a read-only property.
//question
// 实现一个 Mutable 工具类型,用于移除对象类型上所有属性或部分属性的 readonly 修饰符。具体的使用示例如下所示:
// type Foo = {
// readonly a: number;
// readonly b: string;
// readonly c: boolean;
// };
// type Mutable<T, Keys extends keyof T = keyof T> = // 你的实现代码
// const mutableFoo: Mutable<Foo, 'a'> = { a: 1, b: '2', c: true };
// mutableFoo.a = 3; // OK
// mutableFoo.b = '6'; // Cannot assign to 'b' because it is a read-only property.
//answer
type Simplify<T> = {
[K in keyof T]: T[K]
}
type Mutable<T, Keys extends keyof T = keyof T> = Simplify<
{
-readonly [K in Keys]: T[K]
} & Omit<T, Keys>
>
type Foo1 = {
readonly a: number
readonly b: string
readonly c: boolean
}
const mutableFoo: Mutable<Foo1, 'a'> = { a: 1, b: '2', c: true }
mutableFoo.a = 3 // OK
mutableFoo.b = '6' // Cannot assign to 'b' because it is a read-only property.
type Mutables<T, Keys extends keyof T = keyof T> = { -readonly [V in keyof T as V extends Keys ? V : never]: T[V] } & { [S in keyof T as S extends Keys ? never : S]: T[S] }
type Mutable<T, Keys extends keyof T = keyof T> = Omit<T, Keys> & {
-readonly [P in Keys]: T[P]
}
type Mutable<T, Keys extends keyof T = keyof T> = Keys extends string ? Record<Keys, T[Keys]> & Omit<Foo, Keys> : never
type Mutable<T, Keys extends keyof T = keyof T> = {
- readonly [k in Keys]: T[k]
} & Omit<T,Keys> // 你的实现代码
type Foo = {
readonly a: number;
readonly b: string;
readonly c: boolean;
};
type Mutable<T, Keys extends keyof T = keyof T> = Omit<T, Keys> & {
- readonly[K in keyof T as (K extends Keys ? K : never)]: T[K]
}
const mutableFoo: Mutable<Foo, 'a'> = { a: 1, b: '2', c: true };
mutableFoo.a = 3; // OK
mutableFoo.b = '6'; // Cannot assign to 'b' because it is a read-only property.