Skip to content

Commit

Permalink
Run ESLINT_USE_FLAT_CONFIG=true eslint -c eslint.config.js . --fix
Browse files Browse the repository at this point in the history
  • Loading branch information
aryaemami59 committed Mar 22, 2024
1 parent b708fce commit 7858e97
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 25 deletions.
55 changes: 44 additions & 11 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -297,34 +297,64 @@ const inverted = Symbol('inverted')
type Inverted<T> = {[inverted]: T}

const expectNull = Symbol('expectNull')
type ExpectNull<T> = {[expectNull]: T; result: ExtendsExcludingAnyOrNever<T, null>}
type ExpectNull<T> = {
[expectNull]: T
result: ExtendsExcludingAnyOrNever<T, null>
}

const expectUndefined = Symbol('expectUndefined')
type ExpectUndefined<T> = {[expectUndefined]: T; result: ExtendsExcludingAnyOrNever<T, undefined>}
type ExpectUndefined<T> = {
[expectUndefined]: T
result: ExtendsExcludingAnyOrNever<T, undefined>
}

const expectNumber = Symbol('expectNumber')
type ExpectNumber<T> = {[expectNumber]: T; result: ExtendsExcludingAnyOrNever<T, number>}
type ExpectNumber<T> = {
[expectNumber]: T
result: ExtendsExcludingAnyOrNever<T, number>
}

const expectString = Symbol('expectString')
type ExpectString<T> = {[expectString]: T; result: ExtendsExcludingAnyOrNever<T, string>}
type ExpectString<T> = {
[expectString]: T
result: ExtendsExcludingAnyOrNever<T, string>
}

const expectBoolean = Symbol('expectBoolean')
type ExpectBoolean<T> = {[expectBoolean]: T; result: ExtendsExcludingAnyOrNever<T, boolean>}
type ExpectBoolean<T> = {
[expectBoolean]: T
result: ExtendsExcludingAnyOrNever<T, boolean>
}

const expectVoid = Symbol('expectVoid')
type ExpectVoid<T> = {[expectVoid]: T; result: ExtendsExcludingAnyOrNever<T, void>}
type ExpectVoid<T> = {
[expectVoid]: T
result: ExtendsExcludingAnyOrNever<T, void>
}

const expectFunction = Symbol('expectFunction')
type ExpectFunction<T> = {[expectFunction]: T; result: ExtendsExcludingAnyOrNever<T, (...args: any[]) => any>}
type ExpectFunction<T> = {
[expectFunction]: T
result: ExtendsExcludingAnyOrNever<T, (...args: any[]) => any>
}

const expectObject = Symbol('expectObject')
type ExpectObject<T> = {[expectObject]: T; result: ExtendsExcludingAnyOrNever<T, object>}
type ExpectObject<T> = {
[expectObject]: T
result: ExtendsExcludingAnyOrNever<T, object>
}

const expectArray = Symbol('expectArray')
type ExpectArray<T> = {[expectArray]: T; result: ExtendsExcludingAnyOrNever<T, any[]>}
type ExpectArray<T> = {
[expectArray]: T
result: ExtendsExcludingAnyOrNever<T, any[]>
}

const expectSymbol = Symbol('expectSymbol')
type ExpectSymbol<T> = {[expectSymbol]: T; result: ExtendsExcludingAnyOrNever<T, symbol>}
type ExpectSymbol<T> = {
[expectSymbol]: T
result: ExtendsExcludingAnyOrNever<T, symbol>
}

const expectAny = Symbol('expectAny')
type ExpectAny<T> = {[expectAny]: T; result: IsAny<T>}
Expand All @@ -336,7 +366,10 @@ const expectNever = Symbol('expectNever')
type ExpectNever<T> = {[expectNever]: T; result: IsNever<T>}

const expectNullable = Symbol('expectNullable')
type ExpectNullable<T> = {[expectNullable]: T; result: Not<StrictEqualUsingBranding<T, NonNullable<T>>>}
type ExpectNullable<T> = {
[expectNullable]: T
result: Not<StrictEqualUsingBranding<T, NonNullable<T>>>
}

/**
* Represents a scolder function that checks if the result of an expecter
Expand Down
60 changes: 46 additions & 14 deletions test/types.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -624,19 +624,27 @@ test('Distinguish between different types that are OR`d together', () => {
// @ts-expect-error
expectTypeOf<{foo: number} | {bar: string}>().not.toEqualTypeOf<{foo: number} | {bar: string}>()

expectTypeOf<{foo: number} | {bar: string}>().not.toEqualTypeOf<{foo: number}>()
expectTypeOf<{foo: number} | {bar: string}>().not.toEqualTypeOf<{
foo: number
}>()
// @ts-expect-error
expectTypeOf<{foo: number} | {bar: string}>().toEqualTypeOf<{foo: number}>()
expectTypeOf<{foo: number} | {bar: string}>().toEqualTypeOf<{
foo: number
}>()
})

test('Distinguish between identical types that are OR`d together', () => {
expectTypeOf<{foo: number} | {foo: number}>().toEqualTypeOf<{foo: number} | {foo: number}>()
// Note: The `| T` in `Equal` in index.ts makes this work.
expectTypeOf<{foo: number} | {foo: number}>().toEqualTypeOf<{foo: number}>()
expectTypeOf<{foo: number} | {foo: number}>().toEqualTypeOf<{
foo: number
}>()
// @ts-expect-error
expectTypeOf<{foo: number} | {foo: number}>().not.toEqualTypeOf<{foo: number} | {foo: number}>()
// @ts-expect-error
expectTypeOf<{foo: number} | {foo: number}>().not.toEqualTypeOf<{foo: number}>()
expectTypeOf<{foo: number} | {foo: number}>().not.toEqualTypeOf<{
foo: number
}>()
})

test('Distinguish between different types that are AND`d together', () => {
Expand All @@ -653,9 +661,15 @@ test('Distinguish between different types that are AND`d together', () => {

test('Works arounds tsc bug not handling intersected types for this form of equivalence', () => {
// @ts-expect-error This is the bug.
expectTypeOf<{foo: number} & {bar: string}>().toEqualTypeOf<{foo: number; bar: string}>()
expectTypeOf<{foo: number} & {bar: string}>().toEqualTypeOf<{
foo: number
bar: string
}>()
// This should \@ts-expect-error but does not.
expectTypeOf<{foo: number} & {bar: string}>().not.toEqualTypeOf<{foo: number; bar: string}>()
expectTypeOf<{foo: number} & {bar: string}>().not.toEqualTypeOf<{
foo: number
bar: string
}>()

const one: {foo: number} & {bar: string} = {foo: 1, bar: 'a'}
const two: {foo: number; bar: string} = {foo: 1, bar: 'a'}
Expand All @@ -665,24 +679,36 @@ test('Works arounds tsc bug not handling intersected types for this form of equi
expectTypeOf(one).not.toEqualTypeOf(two)

// The workaround is the new optional .branded modifier.
expectTypeOf<{foo: number} & {bar: string}>().branded.toEqualTypeOf<{foo: number; bar: string}>()
expectTypeOf<{foo: number} & {bar: string}>().branded.toEqualTypeOf<{
foo: number
bar: string
}>()
expectTypeOf(one).branded.toEqualTypeOf<typeof two>()
// @ts-expect-error
expectTypeOf<{foo: number} & {bar: string}>().branded.not.toEqualTypeOf<{foo: number; bar: string}>()
expectTypeOf<{foo: number} & {bar: string}>().branded.not.toEqualTypeOf<{
foo: number
bar: string
}>()
// @ts-expect-error
expectTypeOf(one).branded.not.toEqualTypeOf(two)
})

test('Distinguish between identical types that are AND`d together', () => {
expectTypeOf<{foo: number} & {foo: number}>().toEqualTypeOf<{foo: number} & {foo: number}>()
// Note: The `& T` in `Equal` in index.ts makes this work.
expectTypeOf<{foo: number} & {foo: number}>().toEqualTypeOf<{foo: number}>()
expectTypeOf<{foo: number} & {foo: number}>().toEqualTypeOf<{
foo: number
}>()
// @ts-expect-error
expectTypeOf<{foo: number} & {foo: number}>().not.toEqualTypeOf<{foo: number} & {foo: number}>()
// @ts-expect-error
expectTypeOf<{foo: number} & {foo: number}>().not.toEqualTypeOf<{foo: number}>()
expectTypeOf<{foo: number} & {foo: number}>().not.toEqualTypeOf<{
foo: number
}>()

expectTypeOf<{a: {b: 1} & {c: 1}}>().branded.toEqualTypeOf<{a: {b: 1; c: 1}}>()
expectTypeOf<{a: {b: 1} & {c: 1}}>().branded.toEqualTypeOf<{
a: {b: 1; c: 1}
}>()
expectTypeOf<() => () => () => {a: 1} & {b: 1}>().not.toEqualTypeOf<() => () => () => {a: 1; c: 1}>()

expectTypeOf<{foo: number} & {foo: number}>().toEqualTypeOf<{foo: number} & {foo: number}>()
Expand All @@ -696,9 +722,13 @@ test('limitations', () => {
expectTypeOf<a.StrictEqualUsingBranding<() => () => () => void, () => () => () => string>>().toEqualTypeOf<false>()

// @ts-expect-error toEqualTypeOf relies on TypeScript's internal `toBeIdentical` function which falls down with intersection types, but is otherwise accurate and performant: https://github.com/microsoft/TypeScript/issues/55188#issuecomment-1656328122
expectTypeOf<{a: {b: 1} & {c: 1}}>().toEqualTypeOf<{a: {b: 1; c: 1}}>()
expectTypeOf<{a: {b: 1} & {c: 1}}>().toEqualTypeOf<{
a: {b: 1; c: 1}
}>()
// use `.branded` to get around this, at the cost of performance.
expectTypeOf<{a: {b: 1} & {c: 1}}>().branded.toEqualTypeOf<{a: {b: 1; c: 1}}>()
expectTypeOf<{a: {b: 1} & {c: 1}}>().branded.toEqualTypeOf<{
a: {b: 1; c: 1}
}>()
})

test('PrintType', () => {
Expand Down Expand Up @@ -729,7 +759,9 @@ test('Issue #53: `.omit()` should work similarly to `Omit`', () => {
code: number
}

expectTypeOf<Omit<Loading | Failed, 'code'>>().toEqualTypeOf<{state: 'loading' | 'failed'}>()
expectTypeOf<Omit<Loading | Failed, 'code'>>().toEqualTypeOf<{
state: 'loading' | 'failed'
}>()

expectTypeOf<Loading | Failed>().omit<'code'>().toEqualTypeOf<{state: 'loading' | 'failed'}>()
})
Expand Down

0 comments on commit 7858e97

Please sign in to comment.