Skip to content

Commit 12df298

Browse files
fix: remove .value field from type declarations for boolean literal types (#535)
## PR Checklist - [x] Addresses an existing open issue: fixes #528 - [x] That issue was marked as [`status: accepting prs`](https://github.com/JoshuaKGoldberg/ts-api-utils/issues?q=is%3Aopen+is%3Aissue+label%3A%22status%3A+accepting+prs%22) - [x] Steps in [CONTRIBUTING.md](https://github.com/JoshuaKGoldberg/ts-api-utils/blob/main/.github/CONTRIBUTING.md) were taken ## Overview Ostensibly, this is the code change, but it looks pretty intentional that it was written this way in the first place, so.... maybe needs some more investigation in order to understand why it was written this way. <s>I'm not really sure how to test for this, either. I've written a test that proves the bug's existence, but wouldn't prevent it from regressing. Open to suggestions 🤔</s> I've written a test that proves the bug's existence at runtime, _and_ will cause a type-checking error if the `value` field is added back, due to its use of `@ts-expect-error` --------- Co-authored-by: Rebecca Stevens <rebecca.stevens@outlook.co.nz>
1 parent a9fcaa7 commit 12df298

2 files changed

Lines changed: 28 additions & 5 deletions

File tree

src/types/typeGuards/literal.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ import { describe, expect, it } from "vitest";
33

44
import { createSourceFileAndTypeChecker } from "../../test/utils";
55
import {
6+
BooleanLiteralType,
67
isBigIntLiteralType,
8+
isBooleanLiteralType,
79
isFalseLiteralType,
810
isLiteralType,
911
isNumberLiteralType,
@@ -40,3 +42,24 @@ describe.each([
4042
});
4143
});
4244
});
45+
46+
describe("booleans don't have .value", () => {
47+
for (const trueOrFalse of ["true", "false"]) {
48+
it(`should show that ${trueOrFalse} is a boolean literal type but doesn't have a .value field`, () => {
49+
const { sourceFile, typeChecker } = createSourceFileAndTypeChecker(`
50+
declare const x: ${trueOrFalse};
51+
`);
52+
53+
const node = (sourceFile.statements[0] as ts.VariableStatement)
54+
.declarationList.declarations[0].name;
55+
56+
const type = typeChecker.getTypeAtLocation(node);
57+
58+
expect(isBooleanLiteralType(type)).toBe(true);
59+
const booleanLiteralType = type as BooleanLiteralType;
60+
expect(booleanLiteralType.intrinsicName).toEqual(trueOrFalse);
61+
62+
expect(booleanLiteralType).not.toHaveProperty("value");
63+
});
64+
}
65+
});

src/types/typeGuards/literal.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,8 @@ import { type FreshableIntrinsicType } from "./compound";
88
* i.e. Either a "true" or "false" literal.
99
* @category Type Types
1010
*/
11-
export interface BooleanLiteralType extends UnknownLiteralType {
11+
export interface BooleanLiteralType extends FreshableIntrinsicType {
1212
intrinsicName: "false" | "true";
13-
value: boolean;
1413
}
1514

1615
/**
@@ -55,7 +54,6 @@ export function isBigIntLiteralType(
5554
*/
5655
export interface FalseLiteralType extends BooleanLiteralType {
5756
intrinsicName: "false";
58-
value: false;
5957
}
6058

6159
/**
@@ -150,7 +148,6 @@ export function isTemplateLiteralType(
150148
*/
151149
export interface TrueLiteralType extends BooleanLiteralType {
152150
intrinsicName: "true";
153-
value: true;
154151
}
155152

156153
/**
@@ -171,14 +168,16 @@ export function isTrueLiteralType(type: ts.Type): type is TrueLiteralType {
171168

172169
/**
173170
* `LiteralType` from typescript except that it allows for it to work on arbitrary types.
171+
* @deprecated Use {@link FreshableIntrinsicType} instead.
174172
* @category Type Types
175173
*/
176174
export interface UnknownLiteralType extends FreshableIntrinsicType {
177-
value: unknown;
175+
value?: unknown;
178176
}
179177

180178
/**
181179
* Test if a type is a {@link UnknownLiteralType}.
180+
* @deprecated Use {@link isFreshableIntrinsicType} instead.
182181
* @category Types - Type Guards
183182
* @example
184183
* ```ts
@@ -191,6 +190,7 @@ export interface UnknownLiteralType extends FreshableIntrinsicType {
191190
*/
192191
export function isUnknownLiteralType(
193192
type: ts.Type,
193+
// eslint-disable-next-line deprecation/deprecation
194194
): type is UnknownLiteralType {
195195
return isTypeFlagSet(type, ts.TypeFlags.Literal);
196196
}

0 commit comments

Comments
 (0)