Skip to content

Commit

Permalink
test: update tests for IsNotStringLiteral
Browse files Browse the repository at this point in the history
  • Loading branch information
unional committed Mar 24, 2024
1 parent 15e6bf0 commit 9c859cd
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 94 deletions.
208 changes: 115 additions & 93 deletions packages/type-plus/src/string/is_not_string_literal.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ it('returns false if T is a string literal', () => {
testType.false<IsNotStringLiteral<'a'>>(true)
})

it('returns false if T is a template string literal', () => {
it('returns false if T is a template literal', () => {
testType.false<IsNotStringLiteral<`${boolean}`>>(true)
testType.false<IsNotStringLiteral<`a${number}`>>(true)
testType.false<IsNotStringLiteral<`${bigint}c`>>(true)
Expand All @@ -24,7 +24,7 @@ it('returns false for Uppercase string literal', () => {
testType.false<IsNotStringLiteral<Uppercase<'abc'>>>(true)
})

it('returns false for Uppercase template string literal', () => {
it('returns false for Uppercase template literal', () => {
testType.false<IsNotStringLiteral<Uppercase<`${true}`>>>(true)
testType.false<IsNotStringLiteral<Uppercase<`${undefined}c`>>>(true)
})
Expand All @@ -40,7 +40,7 @@ it('returns false for Lowercase string literal', () => {
testType.false<IsNotStringLiteral<Lowercase<'foo'>>>(true)
})

it('returns false for Lowercase template string literal', () => {
it('returns false for Lowercase template literal', () => {
testType.false<IsNotStringLiteral<Lowercase<`${false}`>>>(true)
testType.false<IsNotStringLiteral<Lowercase<`a${1}`>>>(true)
testType.false<IsNotStringLiteral<Lowercase<`${1n}c`>>>(true)
Expand Down Expand Up @@ -89,10 +89,48 @@ it('distributes over union type', () => {
})

it('works with intersection type', () => {
testType.equal<IsNotStringLiteral<string & { a: 1 }>, true>(true)
testType.equal<IsNotStringLiteral<string & { a: 1 }, { distributive: false }>, true>(true)
testType.equal<IsNotStringLiteral<'' & { a: 1 }>, false>(true)
testType.equal<IsNotStringLiteral<'' & { a: 1 }, { distributive: false }>, false>(true)
testType.true<IsNotStringLiteral<number & { a: 1 }>>(true)
testType.true<IsNotStringLiteral<string & { a: 1 }>>(true)
testType.false<IsNotStringLiteral<'' & { a: 1 }>>(true)
testType.false<IsNotStringLiteral<'abc' & { a: 1 }>>(true)
testType.false<IsNotStringLiteral<`a-${number}` & { a: 1 }>>(true)
})

it('works as filter', () => {
testType.equal<IsNotStringLiteral<string, { selection: 'filter' }>, string>(true)
testType.equal<IsNotStringLiteral<'', { selection: 'filter' }>, never>(true)

testType.equal<IsNotStringLiteral<never, { selection: 'filter' }>, never>(true)
testType.equal<IsNotStringLiteral<unknown, { selection: 'filter' }>, unknown>(true)
testType.equal<IsNotStringLiteral<string | number, { selection: 'filter' }>, string | number>(true)

testType.equal<IsNotStringLiteral<'' | 1, { selection: 'filter' }>, 1>(true)
})

it('works with unique branches', () => {
testType.equal<IsNotStringLiteral<string, IsNotStringLiteral.$Branch>, $Then>(true)
testType.equal<IsNotStringLiteral<'a', IsNotStringLiteral.$Branch>, $Else>(true)
testType.equal<IsNotStringLiteral<'a', { $then: String, $else: never }>, never>(true)

testType.equal<IsNotStringLiteral<any, IsNotStringLiteral.$Branch>, $Then>(true)
testType.equal<IsNotStringLiteral<unknown, IsNotStringLiteral.$Branch>, $Then>(true)
testType.equal<IsNotStringLiteral<never, IsNotStringLiteral.$Branch>, $Then>(true)
testType.equal<IsNotStringLiteral<void, IsNotStringLiteral.$Branch>, $Then>(true)
})

it('can override $any branch', () => {
testType.equal<IsNotStringLiteral<any>, true>(true)
testType.equal<IsNotStringLiteral<any, { $any: unknown }>, unknown>(true)
})

it('can override $unknown branch', () => {
testType.equal<IsNotStringLiteral<unknown>, true>(true)
testType.equal<IsNotStringLiteral<unknown, { $unknown: unknown }>, unknown>(true)
})

it('can override $never branch', () => {
testType.equal<IsNotStringLiteral<never>, true>(true)
testType.equal<IsNotStringLiteral<never, { $never: unknown }>, unknown>(true)
})

describe('disable distribution', () => {
Expand All @@ -102,9 +140,10 @@ describe('disable distribution', () => {

it('returns false if T is a string literal', () => {
testType.false<IsNotStringLiteral<'', { distributive: false }>>(true)
testType.false<IsNotStringLiteral<'a', { distributive: false }>>(true)
})

it('returns false if T is a template string literal', () => {
it('returns false if T is a template literal', () => {
testType.false<IsNotStringLiteral<`${false}`, { distributive: false }>>(true)
testType.false<IsNotStringLiteral<`a${1.1}`, { distributive: false }>>(true)
testType.false<IsNotStringLiteral<`${-1}c`, { distributive: false }>>(true)
Expand All @@ -114,7 +153,7 @@ describe('disable distribution', () => {
testType.false<IsNotStringLiteral<Uppercase<'abc'>, { distributive: false }>>(true)
})

it('returns false for Uppercase template string literal', () => {
it('returns false for Uppercase template literal', () => {
testType.false<IsNotStringLiteral<Uppercase<`${false}`>, { distributive: false }>>(true)
testType.false<IsNotStringLiteral<Uppercase<`a${undefined}`>, { distributive: false }>>(true)
})
Expand All @@ -131,7 +170,7 @@ describe('disable distribution', () => {
testType.false<IsNotStringLiteral<Lowercase<'abc'>, { distributive: false }>>(true)
})

it('returns false for Lowercase template string literal', () => {
it('returns false for Lowercase template literal', () => {
testType.false<IsNotStringLiteral<Lowercase<`${number}`>, { distributive: false }>>(true)
testType.false<IsNotStringLiteral<Lowercase<`a${1n}`>, { distributive: false }>>(true)
testType.false<IsNotStringLiteral<Lowercase<`a${undefined}c`>, { distributive: false }>>(true)
Expand Down Expand Up @@ -175,46 +214,16 @@ describe('disable distribution', () => {
it('over union', () => {
testType.equal<IsNotStringLiteral<'a' | number, { distributive: false }>, true>(true)
})
})

it('works as filter', () => {
testType.equal<IsNotStringLiteral<string, { selection: 'filter' }>, string>(true)
testType.equal<IsNotStringLiteral<'', { selection: 'filter' }>, never>(true)

testType.equal<IsNotStringLiteral<never, { selection: 'filter' }>, never>(true)
testType.equal<IsNotStringLiteral<unknown, { selection: 'filter' }>, unknown>(true)
testType.equal<IsNotStringLiteral<string | number, { selection: 'filter' }>, string | number>(true)

testType.equal<IsNotStringLiteral<'' | 1, { selection: 'filter' }>, 1>(true)
})

it('works with unique branches', () => {
testType.equal<IsNotStringLiteral<string, IsNotStringLiteral.$Branch>, $Then>(true)
testType.equal<IsNotStringLiteral<'a', IsNotStringLiteral.$Branch>, $Else>(true)
testType.equal<IsNotStringLiteral<'a', { $then: String, $else: never }>, never>(true)

testType.equal<IsNotStringLiteral<any, IsNotStringLiteral.$Branch>, $Then>(true)
testType.equal<IsNotStringLiteral<unknown, IsNotStringLiteral.$Branch>, $Then>(true)
testType.equal<IsNotStringLiteral<never, IsNotStringLiteral.$Branch>, $Then>(true)
testType.equal<IsNotStringLiteral<void, IsNotStringLiteral.$Branch>, $Then>(true)
})

it('can override $any branch', () => {
testType.equal<IsNotStringLiteral<any>, true>(true)
testType.equal<IsNotStringLiteral<any, { $any: unknown }>, unknown>(true)
})

it('can override $unknown branch', () => {
testType.equal<IsNotStringLiteral<unknown>, true>(true)
testType.equal<IsNotStringLiteral<unknown, { $unknown: unknown }>, unknown>(true)
})

it('can override $never branch', () => {
testType.equal<IsNotStringLiteral<never>, true>(true)
testType.equal<IsNotStringLiteral<never, { $never: unknown }>, unknown>(true)
it('works with intersection type', () => {
testType.true<IsNotStringLiteral<123 & { a: 1 }, { distributive: false }>>(true)
testType.true<IsNotStringLiteral<string & { a: 1 }, { distributive: false }>>(true)
testType.false<IsNotStringLiteral<'' & { a: 1 }, { distributive: false }>>(true)
testType.false<IsNotStringLiteral<`a-${number}` & { a: 1 }, { distributive: false }>>(true)
})
})

describe('exact', () => {
describe('enable exact', () => {
it('returns true for string', () => {
testType.true<IsNotStringLiteral<string, { exact: true }>>(true)
})
Expand All @@ -224,14 +233,14 @@ describe('exact', () => {
testType.false<IsNotStringLiteral<'a', { exact: true }>>(true)
})

it('returns false if T is a template string literal reducible to simple string literal', () => {
it('returns false if T is a template literal reducible to string literal', () => {
testType.false<IsNotStringLiteral<`${''}`, { exact: true }>>(true)
testType.false<IsNotStringLiteral<`a${'b'}`, { exact: true }>>(true)
testType.false<IsNotStringLiteral<`${boolean}c`, { exact: true }>>(true)
testType.false<IsNotStringLiteral<`a${1}c`, { exact: true }>>(true)
})

it('returns true if T is a non-reducible template string literal', () => {
it('returns true if T is a non-reducible template literal', () => {
testType.true<IsNotStringLiteral<`${number}`, { exact: true }>>(true)
testType.true<IsNotStringLiteral<`a${string}`, { exact: true }>>(true)
testType.true<IsNotStringLiteral<`${bigint}c`, { exact: true }>>(true)
Expand All @@ -251,7 +260,7 @@ describe('exact', () => {
testType.true<IsNotStringLiteral<Lowercase<Lowercase<Uppercase<string>>>, { exact: true }>>(true)
})

it('returns false for intrinsic manipulative types with template string literal reducible to simple string literal', () => {
it('returns false for intrinsic manipulative types with template literal reducible to string literal', () => {
testType.false<IsNotStringLiteral<Uppercase<`${''}`>, { exact: true }>>(true)
testType.false<IsNotStringLiteral<Lowercase<`${'b'}`>, { exact: true }>>(true)
testType.false<IsNotStringLiteral<Capitalize<`${boolean}`>, { exact: true }>>(true)
Expand Down Expand Up @@ -294,11 +303,51 @@ describe('exact', () => {
testType.equal<IsNotStringLiteral<'a' | number, { exact: true }>, boolean>(true)
})

it('works with intersection type', () => {
testType.equal<IsNotStringLiteral<string & { a: 1 }, { exact: true }>, true>(true)
testType.equal<IsNotStringLiteral<string & { a: 1 }, { distributive: false, exact: true }>, true>(true)
testType.equal<IsNotStringLiteral<'' & { a: 1 }, { exact: true }>, false>(true)
testType.equal<IsNotStringLiteral<'' & { a: 1 }, { distributive: false, exact: true }>, false>(true)
it.skip('works with intersection type', () => {
testType.true<IsNotStringLiteral<123 & { a: 1 }, { exact: true }>>(true)
testType.true<IsNotStringLiteral<string & { a: 1 }, { exact: true }>>(true)
// FIXME: https://github.com/microsoft/TypeScript/issues/57776
// @ts-expect-error
testType.false<IsNotStringLiteral<'' & { a: 1 }, { exact: true }>>(true)
// @ts-expect-error
testType.false<IsNotStringLiteral<`a-${number}` & { a: 1 }, { exact: true }>>(true)
})

it('works as filter', () => {
testType.equal<IsNotStringLiteral<string, { selection: 'filter', exact: true }>, string>(true)
testType.equal<IsNotStringLiteral<'', { selection: 'filter', exact: true }>, never>(true)

testType.equal<IsNotStringLiteral<never, { selection: 'filter', exact: true }>, never>(true)
testType.equal<IsNotStringLiteral<unknown, { selection: 'filter', exact: true }>, unknown>(true)
testType.equal<IsNotStringLiteral<string | number, { selection: 'filter', exact: true }>, string | number>(true)

testType.equal<IsNotStringLiteral<'' | 1, { selection: 'filter', exact: true }>, 1>(true)
})

it('works with unique branches', () => {
testType.equal<IsNotStringLiteral<string, IsNotStringLiteral.$Branch<{ exact: true }>>, $Then>(true)
testType.equal<IsNotStringLiteral<'a', IsNotStringLiteral.$Branch<{ exact: true }>>, $Else>(true)
testType.equal<IsNotStringLiteral<'a', { $then: String, $else: never, exact: true }>, never>(true)

testType.equal<IsNotStringLiteral<any, IsNotStringLiteral.$Branch<{ exact: true }>>, $Then>(true)
testType.equal<IsNotStringLiteral<unknown, IsNotStringLiteral.$Branch<{ exact: true }>>, $Then>(true)
testType.equal<IsNotStringLiteral<never, IsNotStringLiteral.$Branch<{ exact: true }>>, $Then>(true)
testType.equal<IsNotStringLiteral<void, IsNotStringLiteral.$Branch<{ exact: true }>>, $Then>(true)
})

it('can override $any branch', () => {
testType.equal<IsNotStringLiteral<any, { exact: true }>, true>(true)
testType.equal<IsNotStringLiteral<any, { $any: unknown, exact: true }>, unknown>(true)
})

it('can override $unknown branch', () => {
testType.equal<IsNotStringLiteral<unknown, { exact: true }>, true>(true)
testType.equal<IsNotStringLiteral<unknown, { $unknown: unknown, exact: true }>, unknown>(true)
})

it('can override $never branch', () => {
testType.equal<IsNotStringLiteral<never, { exact: true }>, true>(true)
testType.equal<IsNotStringLiteral<never, { $never: unknown, exact: true }>, unknown>(true)
})

describe('disable distribution', () => {
Expand All @@ -311,15 +360,15 @@ describe('exact', () => {
testType.false<IsNotStringLiteral<'a', { distributive: false, exact: true }>>(true)
})

it('returns false if T is a template string literal reducible to simple string literal', () => {
it('returns false if T is a template literal reducible to string literal', () => {
testType.false<IsNotStringLiteral<`${''}`, { distributive: false, exact: true }>>(true)
testType.false<IsNotStringLiteral<`a${boolean}`, { distributive: false, exact: true }>>(true)
testType.false<IsNotStringLiteral<`${false}c`, { distributive: false, exact: true }>>(true)
testType.false<IsNotStringLiteral<`${1}c`, { distributive: false, exact: true }>>(true)
testType.false<IsNotStringLiteral<`a${1n}c`, { distributive: false, exact: true }>>(true)
})

it('returns true if T is a template string literal', () => {
it('returns true if T is a template literal', () => {
testType.true<IsNotStringLiteral<`${number}`, { distributive: false, exact: true }>>(true)
testType.true<IsNotStringLiteral<`a${bigint}`, { distributive: false, exact: true }>>(true)
testType.true<IsNotStringLiteral<`${string}c`, { distributive: false, exact: true }>>(true)
Expand Down Expand Up @@ -383,42 +432,15 @@ describe('exact', () => {
it('over union', () => {
testType.equal<IsNotStringLiteral<'a' | number, { distributive: false, exact: true }>, true>(true)
})
})

it('works as filter', () => {
testType.equal<IsNotStringLiteral<string, { selection: 'filter', exact: true }>, string>(true)
testType.equal<IsNotStringLiteral<'', { selection: 'filter', exact: true }>, never>(true)

testType.equal<IsNotStringLiteral<never, { selection: 'filter', exact: true }>, never>(true)
testType.equal<IsNotStringLiteral<unknown, { selection: 'filter', exact: true }>, unknown>(true)
testType.equal<IsNotStringLiteral<string | number, { selection: 'filter', exact: true }>, string | number>(true)

testType.equal<IsNotStringLiteral<'' | 1, { selection: 'filter', exact: true }>, 1>(true)
})

it('works with unique branches', () => {
testType.equal<IsNotStringLiteral<string, IsNotStringLiteral.$Branch<{ exact: true }>>, $Then>(true)
testType.equal<IsNotStringLiteral<'a', IsNotStringLiteral.$Branch<{ exact: true }>>, $Else>(true)
testType.equal<IsNotStringLiteral<'a', { $then: String, $else: never, exact: true }>, never>(true)

testType.equal<IsNotStringLiteral<any, IsNotStringLiteral.$Branch<{ exact: true }>>, $Then>(true)
testType.equal<IsNotStringLiteral<unknown, IsNotStringLiteral.$Branch<{ exact: true }>>, $Then>(true)
testType.equal<IsNotStringLiteral<never, IsNotStringLiteral.$Branch<{ exact: true }>>, $Then>(true)
testType.equal<IsNotStringLiteral<void, IsNotStringLiteral.$Branch<{ exact: true }>>, $Then>(true)
})

it('can override $any branch', () => {
testType.equal<IsNotStringLiteral<any, { exact: true}>, true>(true)
testType.equal<IsNotStringLiteral<any, { $any: unknown, exact: true}>, unknown>(true)
})

it('can override $unknown branch', () => {
testType.equal<IsNotStringLiteral<unknown, { exact: true}>, true>(true)
testType.equal<IsNotStringLiteral<unknown, { $unknown: unknown, exact: true}>, unknown>(true)
})

it('can override $never branch', () => {
testType.equal<IsNotStringLiteral<never, { exact: true}>, true>(true)
testType.equal<IsNotStringLiteral<never, { $never: unknown, exact: true}>, unknown>(true)
it.skip('works with intersection type', () => {
testType.equal<IsNotStringLiteral<123 & { a: 1 }, { distributive: false, exact: true }>, true>(true)
testType.equal<IsNotStringLiteral<string & { a: 1 }, { distributive: false, exact: true }>, true>(true)
// FIXME: https://github.com/microsoft/TypeScript/issues/57776
// @ts-expect-error
testType.equal<IsNotStringLiteral<'' & { a: 1 }, { distributive: false, exact: true }>, false>(true)
// @ts-expect-error
testType.equal<IsNotStringLiteral<`${number}` & { a: 1 }, { distributive: false, exact: true }>, false>(true)
})
})
})
2 changes: 1 addition & 1 deletion packages/type-plus/src/string/is_string_literal.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ describe('enable exact', () => {
testType.true<IsStringLiteral<'a', { exact: true }>>(true)
})

it('returns true if T is a template literal reducible to simple string literal', () => {
it('returns true if T is a template literal reducible to string literal', () => {
testType.equal<`${''}`, ''>(true)
testType.true<IsStringLiteral<`${''}`, { exact: true }>>(true)
testType.equal<`a-${boolean}`, 'a-true' | `a-false`>(true)
Expand Down

0 comments on commit 9c859cd

Please sign in to comment.