awesome-typescript icon indicating copy to clipboard operation
awesome-typescript copied to clipboard

「重学TS 2.0 」TS 练习题第二十四题

Open semlinker opened this issue 4 years ago • 22 comments

实现一个 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.

请在下面评论你的答案。

semlinker avatar Sep 20 '21 12:09 semlinker

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.

zerolee1231 avatar Sep 20 '21 16:09 zerolee1231

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.

suica avatar Sep 20 '21 16:09 suica

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.

zhaoxiongfei avatar Sep 20 '21 16:09 zhaoxiongfei

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.

pingan8787 avatar Sep 22 '21 16:09 pingan8787

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.

mingzhans avatar Sep 23 '21 14:09 mingzhans

// 实现一个 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 去除只读限制,之后通过交叉 & 来合并二者。

zhaoxiongfei avatar Oct 02 '21 09:10 zhaoxiongfei

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.

Mrlgm avatar Oct 08 '21 08:10 Mrlgm

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.

Flavour86 avatar Nov 04 '21 03:11 Flavour86

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.

a572251465 avatar Dec 03 '21 04:12 a572251465

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'

ShawDuChen avatar Dec 29 '21 06:12 ShawDuChen

平安已经收到你的邮件啦

pingan8787 avatar Dec 29 '21 06:12 pingan8787


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.

Ljp10086 avatar Jan 04 '22 04:01 Ljp10086

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.

zouyk avatar Feb 21 '22 08:02 zouyk

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>

waleiwalei avatar Mar 16 '22 05:03 waleiwalei

// 解法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]
}

ChangerHe avatar May 28 '22 13:05 ChangerHe

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.

heweijian4933 avatar Jun 03 '22 04:06 heweijian4933

//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.

ChuTingzj avatar Jun 06 '22 13:06 ChuTingzj

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] }

hezhisheng1930 avatar Aug 12 '22 06:08 hezhisheng1930

type Mutable<T, Keys extends keyof T = keyof T> = Omit<T, Keys> & {
   -readonly [P in Keys]: T[P]
}

zhixiaotong avatar Feb 03 '23 03:02 zhixiaotong

type Mutable<T, Keys extends keyof T = keyof T> = Keys extends string ? Record<Keys, T[Keys]> & Omit<Foo, Keys> : never

spike-byte avatar Feb 23 '23 09:02 spike-byte

type Mutable<T, Keys extends keyof T = keyof T> =  {
  - readonly [k in  Keys]: T[k]
} & Omit<T,Keys> // 你的实现代码

Sunny264 avatar Jun 01 '23 08:06 Sunny264

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.

SweeperDuan avatar Dec 12 '23 06:12 SweeperDuan