Skip to content

Commit

Permalink
Update Extends to not distribute over union types (#12)
Browse files Browse the repository at this point in the history
Was attempting to use `expectTypeOf` with unioned types and I was
surprised that `expectTypeOf` was always mismatching.

See [this
repro](https://www.typescriptlang.org/play?#code/C4TwDgpgBAogHsCA7AJgZwDwBkA0UBKAfFALxRZQQLLoFQD8UwATgK7QBcUAZgIYA2aCAG4AUKNCQoASVQBLZhADGwfiFKxqqTGhZykAcwA+SVgFsARhGZ5Tl60YtyD+4ITEB6D1B9QAevQS4NAAIgrKqupkusz6xnZWzJRatAkOTi5IwAxMbJw8AkKe3r4B4kFSAGJycBAo8Ija2HhEGgDaWAC6yY20bfjdjCzsUFx8giLiktDVtSiyKOEqahqzdQ00OnqGJuaJtnvpzq7uol6+-oFAA)
showcasing the problems of union types that get stuck in `Extends`.

Note: This only impacts the LHS of the extends.
  • Loading branch information
trevorade authored Oct 21, 2022
1 parent 14cd7e2 commit 55278a6
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 1 deletion.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,13 @@ expectTypeOf(1).not.toBeUndefined()
expectTypeOf(1).not.toBeNullable()
```

Detect assignability of unioned types:

```typescript
expectTypeOf<number>().toMatchTypeOf<string | number>()
expectTypeOf<string | number>().not.toMatchTypeOf<number>()
```

Use `.extract` and `.exclude` to narrow down complex union types:

```typescript
Expand Down
2 changes: 1 addition & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ type ReadonlyEquivalent<X, Y> = Extends<
(<T>() => T extends Y ? true : false)
>

export type Extends<L, R> = IsNever<L> extends true ? IsNever<R> : L extends R ? true : false
export type Extends<L, R> = IsNever<L> extends true ? IsNever<R> : [L] extends [R] ? true : false
export type StrictExtends<L, R> = Extends<DeepBrand<L>, DeepBrand<R>>

export type Equal<Left, Right> = And<[StrictExtends<Left, Right>, StrictExtends<Right, Left>]>
Expand Down
5 changes: 5 additions & 0 deletions test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,11 @@ test('More `.not` examples', () => {
expectTypeOf(1).not.toBeNullable()
})

test('Detect assignability of unioned types', () => {
expectTypeOf<number>().toMatchTypeOf<string | number>()
expectTypeOf<string | number>().not.toMatchTypeOf<number>()
})

test('Use `.extract` and `.exclude` to narrow down complex union types', () => {
type ResponsiveProp<T> = T | T[] | {xs?: T; sm?: T; md?: T}
const getResponsiveProp = <T>(_props: T): ResponsiveProp<T> => ({})
Expand Down

0 comments on commit 55278a6

Please sign in to comment.