From 1a1a5302f4190fca6493fba1a5c15d36a8b76747 Mon Sep 17 00:00:00 2001 From: Kirk Waiblinger Date: Tue, 22 Oct 2024 14:27:27 -0600 Subject: [PATCH 1/8] remove value field --- src/types/typeGuards/literal.ts | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/types/typeGuards/literal.ts b/src/types/typeGuards/literal.ts index 1835c08e..c20ed31c 100644 --- a/src/types/typeGuards/literal.ts +++ b/src/types/typeGuards/literal.ts @@ -10,7 +10,6 @@ import { type FreshableIntrinsicType } from "./compound"; */ export interface BooleanLiteralType extends UnknownLiteralType { intrinsicName: "false" | "true"; - value: boolean; } /** @@ -55,7 +54,6 @@ export function isBigIntLiteralType( */ export interface FalseLiteralType extends BooleanLiteralType { intrinsicName: "false"; - value: false; } /** @@ -150,7 +148,6 @@ export function isTemplateLiteralType( */ export interface TrueLiteralType extends BooleanLiteralType { intrinsicName: "true"; - value: true; } /** @@ -173,9 +170,7 @@ export function isTrueLiteralType(type: ts.Type): type is TrueLiteralType { * `LiteralType` from typescript except that it allows for it to work on arbitrary types. * @category Type Types */ -export interface UnknownLiteralType extends FreshableIntrinsicType { - value: unknown; -} +export interface UnknownLiteralType extends FreshableIntrinsicType {} /** * Test if a type is a {@link UnknownLiteralType}. From 496d9c3284dabf314cf904bf5c008a9daaf26c38 Mon Sep 17 00:00:00 2001 From: Kirk Waiblinger Date: Tue, 22 Oct 2024 14:40:04 -0600 Subject: [PATCH 2/8] test, sort of --- src/types/typeGuards/literal.test.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/types/typeGuards/literal.test.ts b/src/types/typeGuards/literal.test.ts index a2c13be6..9d6f6441 100644 --- a/src/types/typeGuards/literal.test.ts +++ b/src/types/typeGuards/literal.test.ts @@ -3,7 +3,9 @@ import { describe, expect, it } from "vitest"; import { createSourceFileAndTypeChecker } from "../../test/utils"; import { + BooleanLiteralType, isBigIntLiteralType, + isBooleanLiteralType, isFalseLiteralType, isLiteralType, isNumberLiteralType, @@ -40,3 +42,25 @@ describe.each([ }); }); }); + +describe("booleans don't have .value", () => { + for (const tf of ["true", "false"]) { + it("is a boolean literal type", () => { + const { sourceFile, typeChecker } = createSourceFileAndTypeChecker(` + declare const x: ${tf}; + `); + + const node = (sourceFile.statements[0] as ts.VariableStatement) + .declarationList.declarations[0].name; + + const type = typeChecker.getTypeAtLocation(node); + + expect(isBooleanLiteralType(type)).toBe(true); + const booleanLiteralType = type as BooleanLiteralType; + expect(booleanLiteralType.intrinsicName).toEqual(tf); + + // @ts-expect-error: boolean literals don't have a value + expect(booleanLiteralType.value).toBeUndefined(); + }); + } +}); From 638cda24dae78d2d24c70a9087c54feb1c717875 Mon Sep 17 00:00:00 2001 From: Kirk Waiblinger Date: Tue, 22 Oct 2024 14:43:31 -0600 Subject: [PATCH 3/8] slight renaming --- src/types/typeGuards/literal.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/types/typeGuards/literal.test.ts b/src/types/typeGuards/literal.test.ts index 9d6f6441..611d9aba 100644 --- a/src/types/typeGuards/literal.test.ts +++ b/src/types/typeGuards/literal.test.ts @@ -44,10 +44,10 @@ describe.each([ }); describe("booleans don't have .value", () => { - for (const tf of ["true", "false"]) { - it("is a boolean literal type", () => { + for (const trueOrFalse of ["true", "false"]) { + it(`should show that ${trueOrFalse} is a boolean literal type but doesn't have a .value field`, () => { const { sourceFile, typeChecker } = createSourceFileAndTypeChecker(` - declare const x: ${tf}; + declare const x: ${trueOrFalse}; `); const node = (sourceFile.statements[0] as ts.VariableStatement) @@ -57,7 +57,7 @@ describe("booleans don't have .value", () => { expect(isBooleanLiteralType(type)).toBe(true); const booleanLiteralType = type as BooleanLiteralType; - expect(booleanLiteralType.intrinsicName).toEqual(tf); + expect(booleanLiteralType.intrinsicName).toEqual(trueOrFalse); // @ts-expect-error: boolean literals don't have a value expect(booleanLiteralType.value).toBeUndefined(); From 186774dabc0852bb12a14765173e97b797734cb9 Mon Sep 17 00:00:00 2001 From: Kirk Waiblinger Date: Tue, 22 Oct 2024 14:44:23 -0600 Subject: [PATCH 4/8] format template string --- src/types/typeGuards/literal.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/types/typeGuards/literal.test.ts b/src/types/typeGuards/literal.test.ts index 611d9aba..e49fb248 100644 --- a/src/types/typeGuards/literal.test.ts +++ b/src/types/typeGuards/literal.test.ts @@ -47,8 +47,8 @@ describe("booleans don't have .value", () => { for (const trueOrFalse of ["true", "false"]) { it(`should show that ${trueOrFalse} is a boolean literal type but doesn't have a .value field`, () => { const { sourceFile, typeChecker } = createSourceFileAndTypeChecker(` - declare const x: ${trueOrFalse}; - `); + declare const x: ${trueOrFalse}; + `); const node = (sourceFile.statements[0] as ts.VariableStatement) .declarationList.declarations[0].name; From 34a04914726e47ee94e0efb904381a5030573b75 Mon Sep 17 00:00:00 2001 From: Kirk Waiblinger Date: Sun, 17 Nov 2024 13:55:56 -0700 Subject: [PATCH 5/8] punt on the unneeded interface --- src/types/typeGuards/literal.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/types/typeGuards/literal.ts b/src/types/typeGuards/literal.ts index c20ed31c..0b107736 100644 --- a/src/types/typeGuards/literal.ts +++ b/src/types/typeGuards/literal.ts @@ -170,6 +170,9 @@ export function isTrueLiteralType(type: ts.Type): type is TrueLiteralType { * `LiteralType` from typescript except that it allows for it to work on arbitrary types. * @category Type Types */ +// TODO - resolve what to do with this apparently-useless type. +// See https://github.com/JoshuaKGoldberg/ts-api-utils/pull/535#discussion_r1845527367 +// eslint-disable-next-line @typescript-eslint/no-empty-interface export interface UnknownLiteralType extends FreshableIntrinsicType {} /** From 876b60531facca9ba10df11dfa022caeb952bc2f Mon Sep 17 00:00:00 2001 From: Rebecca Stevens Date: Thu, 21 Nov 2024 23:21:15 +1300 Subject: [PATCH 6/8] fix: deprecate UnknownLiteralType --- src/types/typeGuards/literal.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/types/typeGuards/literal.ts b/src/types/typeGuards/literal.ts index 0b107736..2a1e5a2d 100644 --- a/src/types/typeGuards/literal.ts +++ b/src/types/typeGuards/literal.ts @@ -168,15 +168,16 @@ export function isTrueLiteralType(type: ts.Type): type is TrueLiteralType { /** * `LiteralType` from typescript except that it allows for it to work on arbitrary types. + * @deprecated Use {@link FreshableIntrinsicType} instead. * @category Type Types */ -// TODO - resolve what to do with this apparently-useless type. -// See https://github.com/JoshuaKGoldberg/ts-api-utils/pull/535#discussion_r1845527367 -// eslint-disable-next-line @typescript-eslint/no-empty-interface -export interface UnknownLiteralType extends FreshableIntrinsicType {} +export interface UnknownLiteralType extends FreshableIntrinsicType { + value?: unknown; +} /** * Test if a type is a {@link UnknownLiteralType}. + * @deprecated Use {@link isFreshableIntrinsicType} instead. * @category Types - Type Guards * @example * ```ts From 4b98071149c32e8ea80ae78d90a2ffe95d017353 Mon Sep 17 00:00:00 2001 From: Rebecca Stevens Date: Thu, 21 Nov 2024 23:26:35 +1300 Subject: [PATCH 7/8] test: update test --- src/types/typeGuards/literal.test.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/types/typeGuards/literal.test.ts b/src/types/typeGuards/literal.test.ts index e49fb248..7787cd04 100644 --- a/src/types/typeGuards/literal.test.ts +++ b/src/types/typeGuards/literal.test.ts @@ -59,8 +59,7 @@ describe("booleans don't have .value", () => { const booleanLiteralType = type as BooleanLiteralType; expect(booleanLiteralType.intrinsicName).toEqual(trueOrFalse); - // @ts-expect-error: boolean literals don't have a value - expect(booleanLiteralType.value).toBeUndefined(); + expect(booleanLiteralType).not.toHaveProperty("value"); }); } }); From 9af7c380eea08b0fa39daefca596e450e711c62d Mon Sep 17 00:00:00 2001 From: Rebecca Stevens Date: Thu, 21 Nov 2024 23:27:49 +1300 Subject: [PATCH 8/8] fix: use FreshableIntrinsicType instead of UnknownLiteralType --- src/types/typeGuards/literal.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/types/typeGuards/literal.ts b/src/types/typeGuards/literal.ts index 2a1e5a2d..3644051c 100644 --- a/src/types/typeGuards/literal.ts +++ b/src/types/typeGuards/literal.ts @@ -8,7 +8,7 @@ import { type FreshableIntrinsicType } from "./compound"; * i.e. Either a "true" or "false" literal. * @category Type Types */ -export interface BooleanLiteralType extends UnknownLiteralType { +export interface BooleanLiteralType extends FreshableIntrinsicType { intrinsicName: "false" | "true"; } @@ -190,6 +190,7 @@ export interface UnknownLiteralType extends FreshableIntrinsicType { */ export function isUnknownLiteralType( type: ts.Type, + // eslint-disable-next-line deprecation/deprecation ): type is UnknownLiteralType { return isTypeFlagSet(type, ts.TypeFlags.Literal); }