-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Add AtLeastOne type #171
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
# Custom types | ||
|
||
`AtLeastOne` | ||
|
||
Can be used when you want to make at least one key of an object required. | ||
You don't have to specify which key should be required, it will be inferred from the input type. | ||
Useful for example when you have a function that requires at least one of the parameters, but not necessarily all of them. | ||
|
||
```typescript | ||
type TestType = { | ||
a: string; | ||
b: number; | ||
} | ||
|
||
const foo = (params: AtLeastOne<TestType>) => { | ||
// ... | ||
} | ||
|
||
// Valid | ||
foo({ a: 'a' }); | ||
foo({ b: 1 }); | ||
foo({ a: 'a', b: 1 }); | ||
|
||
// Invalid | ||
foo({}); | ||
``` | ||
|
||
`MayOmit` | ||
|
||
Makes K keys optional in T. | ||
Can be used to provide some defaults and merge input on top of it. | ||
Requires you to explicitly specify which keys should be optional. | ||
|
||
```typescript | ||
type TestType = { | ||
a: string; | ||
b: number; | ||
} | ||
|
||
type TestTypeWithOptionalB = MayOmit<TestType, 'b'>; | ||
``` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { assertType } from 'vitest' | ||
import type { AtLeastOne } from './atLeastOne' | ||
|
||
describe('AtLeastOne', () => { | ||
it('makes at least one key of an object required', () => { | ||
interface TestType { | ||
a: string | ||
b: number | ||
} | ||
|
||
const testCase1: AtLeastOne<TestType> = { a: 'a' } | ||
assertType<{ a: string; b?: number }>(testCase1) | ||
|
||
const testCase2: AtLeastOne<TestType> = { b: 1 } | ||
assertType<{ a?: string; b: number }>(testCase2) | ||
|
||
// @ts-expect-error wrong types | ||
const testCase3: AtLeastOne<TestType> = {} | ||
assertType(testCase3) | ||
}) | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export type AtLeastOne<T, U = { [K in keyof T]: Pick<T, K> }> = Partial<T> & U[keyof U] | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you add documentation for it to readme.md? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've added them to |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can you also add negative case?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added negative test ✅
I've also enabled
typecheck
as by default vitest has it disabled - please seevitest.config.mts