Skip to content

Commit

Permalink
feat(PickWritable): Add PickWritable (#72)
Browse files Browse the repository at this point in the history
* feat(PickWritable): Add PickWritable type

* test(PickWritable): Add PickWritable test

* docs(PickWritable): Add PickWritable docs
  • Loading branch information
haejunejung authored Sep 19, 2024
1 parent 0ccc14d commit 0b78650
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 0 deletions.
4 changes: 4 additions & 0 deletions docs/.vitepress/en.mts
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,10 @@ export default defineConfig({
text: 'PickRequired',
link: '/reference/utilities/PickRequired',
},
{
text: 'PickWritable',
link: '/reference/utilities/PickWritable',
},
{
text: 'Simplify',
link: '/reference/utilities/Simplify',
Expand Down
4 changes: 4 additions & 0 deletions docs/.vitepress/ko.mts
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,10 @@ export default defineConfig({
text: 'PickRequired',
link: '/ko/reference/utilities/PickRequired',
},
{
text: 'PickWritable',
link: '/ko/reference/utilities/PickWritable',
},
{
text: 'Simplify',
link: '/ko/reference/utilities/Simplify',
Expand Down
22 changes: 22 additions & 0 deletions docs/ko/reference/utilities/PickWritable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# PickWritable<T, K>

## 개요

선택된 키를 수정가능하도록 만들고 나머지 타입은 변경되지 않은 상태를 유지하는 새로운 타입을 생성해요.

## 문법

```ts
type PickWritable<T, K extends keyof T> = Simplify<
Omit<T, K> & { -readonly [P in K]: T[P] }
>;
```

## 예제

```ts
type T0 = { readonly a: string; readonly b: number; readonly c: boolean };
type E0 = PickWritable<T0, 'a'>; // { a: string, readonly b: number, readonly c: boolean}
type E1 = PickWritable<T0, 'a' | 'b'>; // { a: string, b: number, readonly c: boolean }
type E2 = PickWritable<T0, 'a' | 'b'>; // { a: string, b: number, c: boolean }
```
22 changes: 22 additions & 0 deletions docs/reference/utilities/PickWritable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# PickWritable<T, K>

## Overview

Creates a new type where the specified keys are made writable, while keeping the rest of the type remain unchanged.

## Syntax

```ts
type PickWritable<T, K extends keyof T> = Simplify<
Omit<T, K> & { -readonly [P in K]: T[P] }
>;
```

## Example

```ts
type T0 = { readonly a: string; readonly b: number; readonly c: boolean };
type E0 = PickWritable<T0, 'a'>; // { a: string, readonly b: number, readonly c: boolean}
type E1 = PickWritable<T0, 'a' | 'b'>; // { a: string, b: number, readonly c: boolean }
type E2 = PickWritable<T0, 'a' | 'b'>; // { a: string, b: number, c: boolean }
```
21 changes: 21 additions & 0 deletions source/utilities/PickWritable.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { Simplify } from './Simplify';

/**
* @description
* Creates a new type where the specified keys are made writable,
* while keeping the rest of the type remain unchanged.
*
* @template T - The original type from which keys are being picked.
* @template K - The keys from the original type `T` that should be made writable.
*
* @returns - A new type keys in K made writable.
*
* @example
* type T0 = { readonly a: string, readonly b: number, readonly c: boolean };
* type E0 = PickWritable<T0, 'a'>; // { a: string, readonly b: number, readonly c: boolean}
* type E1 = PickWritable<T0, 'a' | 'b'> // { a: string, b: number, readonly c: boolean }
* type E2 = PickWritable<T0, 'a' | 'b'> // { a: string, b: number, c: boolean }
*/
export type PickWritable<T, K extends keyof T> = Simplify<
Omit<T, K> & { -readonly [P in K]: T[P] }
>;
1 change: 1 addition & 0 deletions source/utilities/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export type { PickNonNullable } from './PickNonNullable';
export type { PickOptional } from './PickOptional';
export type { PickReadonly } from './PickReadonly';
export type { PickRequired } from './PickRequired';
export type { PickWritable } from './PickWritable';
export type { Simplify } from './Simplify';
export type { StrictExclude } from './StrictExclude';
export type { StrictExtract } from './StrictExtract';
Expand Down
39 changes: 39 additions & 0 deletions test-d/utilities/PickWritable.test-d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { PickWritable } from '@/utilities';
import { expectNotAssignable, expectType } from 'tsd';

declare function pickWritable<T, K extends keyof T>(): PickWritable<T, K>;

type T0 = {
readonly a: string;
readonly b: number;
readonly c: boolean;
};

// Update all readonly to writable.
expectType<{ a: string; b: number; c: boolean }>(
pickWritable<T0, 'a' | 'b' | 'c'>()
);

// Update only two readonly to writable.
expectType<{ a: string; b: number; readonly c: boolean }>(
pickWritable<T0, 'a' | 'b'>()
);

// Check the type changes even if readonly types are updated to writable.
expectNotAssignable<{ a: number; b: number; readonly c: boolean }>(
pickWritable<T0, 'c'>()
);

type T1 = {
readonly a: string[];
readonly b: [string, number];
readonly c: { d: string; readonly e: boolean };
};

// Update Array & Tuple & Object
// The property of Object are remained.
expectType<{
a: string[];
b: [string, number];
c: { d: string; readonly e: boolean };
}>(pickWritable<T1, 'a' | 'b' | 'c'>());

0 comments on commit 0b78650

Please sign in to comment.