-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(StrictExclude): Add
StrictExclude
(#40)
* feat(StrictExclude): Add StrictExclude type * test(StrictExclude): Add StrictExclude type test * docs(StrictExclude): Add StrictExclude type documentation
- Loading branch information
1 parent
cc3d311
commit eaee401
Showing
7 changed files
with
160 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
# StrictExclude\<BaseType, ExcludedMembers> | ||
|
||
## 개요 | ||
|
||
이 타입은 TypeScript의 `Exclude` 유틸리티 타입의 더 엄격한 버전이에요. | ||
|
||
`Exclude`는 주어진 타입에 없는 멤버도 제외할 수 있지만, `StrictExclude`는 오직 실제로 타입에 존재하는 멤버만 제외할 수 있도록 보장해요. | ||
|
||
## 문법 | ||
|
||
```ts | ||
type StrictExclude<BaseType, ExcludedMembers extends BaseType> = Exclude< | ||
BaseType, | ||
ExcludedMembers | ||
>; | ||
``` | ||
|
||
- **BaseType**: 유니온 멤버를 제외하고자 하는 기존 타입이에요. | ||
- **ExcludedMembers**: `BaseType`에서 제외하려는 유니온 멤버 혹은 타입이에요. | ||
|
||
## 예제 | ||
|
||
#### 예제 #1 | ||
|
||
```ts | ||
type Example = 'admin' | 'editor' | 'viewer'; | ||
type StrictExcludedExample = StrictExclude<Example, 'admin'>; | ||
// Result: "editor" | "viewer" | ||
``` | ||
|
||
:::tip | ||
If your team is using ESLint and wants to enforce the use of `StrictExclude` instead of the standard `Exclude`, you can configure ESLint to help catch this. The `@typescript-eslint/ban-types` rule can be configured to display an error message when `Exclude` is used, guiding developers to use `StrictExclude` instead. Here's how you can set up your ESLint configuration: | ||
|
||
```js | ||
module.exports = { | ||
parser: '@typescript-eslint/parser', | ||
plugins: ['@typescript-eslint'], | ||
rules: { | ||
// Include other relevant rules here | ||
'@typescript-eslint/ban-types': [ | ||
'error', | ||
{ | ||
types: { | ||
Exclude: 'Use StrictExclude instead', | ||
}, | ||
extendsDefaults: true, | ||
}, | ||
], | ||
}, | ||
}; | ||
``` | ||
|
||
::: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
# StrictExclude\<BaseType, ExcludedMembers> | ||
|
||
## Overview | ||
|
||
This type is a stricter version of TypeScript's `Exclude` utility type. | ||
|
||
Unlike `Exclude`, which allows excluded members not present on the given type, | ||
`StrictExclude` ensures that only members actually present in the type can be excluded. | ||
|
||
## Syntax | ||
|
||
```ts | ||
type StrictExclude<BaseType, ExcludedMembers extends BaseType> = Exclude< | ||
BaseType, | ||
ExcludedMembers | ||
>; | ||
``` | ||
|
||
- **BaseType**: The type from which you want to exclude union members. | ||
- **ExcludedMembers**: The members or types that you want to exclude from `BaseType`. | ||
|
||
## Examples | ||
|
||
#### Example #1 | ||
|
||
```ts | ||
type Example = 'admin' | 'editor' | 'viewer'; | ||
type StrictExcludedExample = StrictExclude<Example, 'admin'>; | ||
// Result: "editor" | "viewer" | ||
``` | ||
|
||
:::tip | ||
If your team is using ESLint and wants to enforce the use of `StrictExclude` instead of the standard `Exclude`, you can configure ESLint to help catch this. The `@typescript-eslint/ban-types` rule can be configured to display an error message when `Exclude` is used, guiding developers to use `StrictExclude` instead. Here's how you can set up your ESLint configuration: | ||
|
||
```js | ||
module.exports = { | ||
parser: '@typescript-eslint/parser', | ||
plugins: ['@typescript-eslint'], | ||
rules: { | ||
// Include other relevant rules here | ||
'@typescript-eslint/ban-types': [ | ||
'error', | ||
{ | ||
types: { | ||
Exclude: 'Use StrictExclude instead', | ||
}, | ||
extendsDefaults: true, | ||
}, | ||
], | ||
}, | ||
}; | ||
``` | ||
|
||
::: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/** | ||
* @description | ||
* This type is a stricter version of TypeScript's `Exclude` utility type. | ||
* | ||
* Unlike `Exclude`, which allows excluded members not present on the given type, | ||
* `StrictExclude` ensures that only members actually present in the type can be excluded. | ||
* | ||
* @template BaseType - The type from which you want to exclude union members. | ||
* @template ExcludedMembers - The members or types that you want to exclude from `BaseType`. | ||
* | ||
* @returns | ||
* A new type that consists of all memebers of `BaseType` except that are assignable to `ExcludedMembers`. | ||
* | ||
* @example | ||
* type Example = "admin" | "editor" | "viewer"; | ||
* type StrictExcludedExample = StrictExclude<Example, "admin"> | ||
* // Result: "editor" | "viewer" | ||
*/ | ||
|
||
export type StrictExclude<BaseType, ExcludedMembers extends BaseType> = Exclude< | ||
BaseType, | ||
ExcludedMembers | ||
>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
export type { StrictExclude } from './StrictExclude'; | ||
export type { StrictOmit } from './StrictOmit'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { StrictExclude } from '@/utilities'; | ||
import { expectNever, expectType } from 'tsd'; | ||
|
||
declare function strictExclude< | ||
BaseType, | ||
ExcludedMembers extends BaseType, | ||
>(): StrictExclude<BaseType, ExcludedMembers>; | ||
|
||
// Should correctly handle basic case. | ||
type Example0 = 'admin' | 'editor' | 'viewer'; | ||
type Expected0 = 'admin' | 'editor'; | ||
expectType<Expected0>(strictExclude<Example0, 'viewer'>()); | ||
|
||
// Should return the original type if excluding no members. | ||
type Example1 = 'a' | 'b' | 'c'; | ||
type Expected1 = 'a' | 'b' | 'c'; | ||
expectType<Expected1>(strictExclude<Example1, never>()); | ||
|
||
// Should return `never` if excluding all members; | ||
type Example2 = 'a' | 'b' | 'c'; | ||
expectNever(strictExclude<Example2, 'a' | 'b' | 'c'>()); |