yunliuyan / type-challenges

typescript-challenges
0 stars 2 forks source link

00001-easy-readonly #2

Open yunliuyan opened 11 months ago

yunliuyan commented 11 months ago

实现 Readonly 简单 #built-in #readonly #object-keys

by Anthony Fu @antfu

接受挑战    English 日本語 한국어

欢迎 PR 改进翻译质量。

不要使用内置的Readonly<T>,自己实现一个。

Readonly 会接收一个 泛型参数,并返回一个完全一样的类型,只是所有属性都会被 readonly 所修饰。

也就是不可以再对该对象的属性赋值。

例如:

interface Todo {
  title: string
  description: string
}

const todo: MyReadonly<Todo> = {
  title: "Hey",
  description: "foobar"
}

todo.title = "Hello" // Error: cannot reassign a readonly property
todo.description = "barFoo" // Error: cannot reassign a readonly property

测试案例:

import type { Equal, Expect } from '@type-challenges/utils'

type cases = [
  Expect<Equal<MyReadonly<Todo1>, Readonly<Todo1>>>,
]

interface Todo1 {
  title: string
  description: string
  completed: boolean
  meta: {
    author: string
  }
}

返回首页 分享你的解答 查看解答

相关挑战

8・Readonly 2 9・深度 Readonly
yunliuyan commented 11 months ago

思路:

只要将对应的属性所有的属性值设置为readonly即可。 遍历key属性方法: key in keyof T 获取value的值方法: T[key]

代码实现

type MyReadonly<T> = {
   readonly [key in keyof T]:  T[key]
}
Janice-Fan commented 11 months ago

https://github.com/yunliuyan/type-challenges/commit/abbf2510a4897b034d3ca05f828c5306e1d0cce8

liangchengv commented 11 months ago
type ReadOnlyType<T> = {
  readonly [P in keyof T]: T[P];
}

interface Todo1 {
  title: string
  description: string
  completed: boolean
  meta: {
    author: string
  }
}

const readOnlyTest: ReadOnlyType<Todo1 > = {
 title: '你好',
  description: '我是描述',
  completed: false,
  meta: {
    author: '凉橙',
  }
}

readOnlyTest.description = '今天周三';
wudu8 commented 11 months ago
/**
 * 实现一个readonly类型,只针对第一层属性只读
 */
type ILoveReadOnly<T> = {
    readonly [k in keyof T]: T[k];
};

interface Todo1 {
    name: string;
    description: string;
    meta: {
        description: string;
    };
}

const readonlyTest: ILoveReadOnly<Todo1> = {
    name: "字节猿",
    description: "字节猿喜欢readonly",
    meta: {
        description: "ILoveReadOnly类型并不支持深层只读",
    },
};

readonlyTest.name = "abc"; // Error: Cannot assign to 'name' because it is a read-only property.ts(2540)
readonlyTest.meta.description = "abc"; // Ok
Naparte commented 11 months ago
type MyReadonly<T> = {
    readonly [key in keyof T]: T[key]
}

interface Todo1 {
    title: string
    description: string
}

const todo1: MyReadonly<Todo1> = {
    title: "Hey",
    description: "foobar"
}

todo1.title = "Hello" // Error: cannot reassign a readonly property
todo1.description = "barFoo" // Error: cannot reassign a readonly property