微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Typescript类型体操 - Readonly 2

题目

中文

实现一个通用MyReadonly2<T, K>,它带有两种类型的参数TK

K指定应设置为Readonly的T属性集。如果未提供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

English

Implement a generic MyReadonly2<T, K> which takes two type argument T and K.

K specify the set of properties of T that should set to Readonly. When K is not provided, it should make all properties readonly just like the normal Readonly<T>.

For example

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

答案

解法一,引入第三个泛型参数O

type MyReadonly2<T, K extends keyof T = keyof T, O extends keyof T = keyof T> = { readonly [P in keyof T]: T[P] } & {
  [P in (O extends K ? never : O)]: T[P]
}

在线演示

解法二,借助MyOmit MyExclude辅助

type MyExclude<T, K> = T extends K ? never : T;
type MyOmit<T, K extends keyof T> = { [P in MyExclude<keyof T, K> ]: T[P] }
type MyReadonly2<T, K extends keyof T = keyof T> = { readonly [P in keyof T]: T[P] } & MyOmit<T, K>

在线演示

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐