Skip to content

Commit c3e980e

Browse files
feat: rename *TypeParts functions to *Constituents (#713)
## PR Checklist - [x] Addresses an existing open issue: fixes #375 - [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 Leaves the old functions as `@deprecated` variables set to the new ones. Updates the suggested variable naming from `typePart` to `constituent`. I at first had tried `typeConstituent` but found it to be kind of long. 💖
1 parent 264b943 commit c3e980e

File tree

2 files changed

+56
-32
lines changed

2 files changed

+56
-32
lines changed

knip.jsonc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
{
22
"$schema": "https://unpkg.com/knip@5/schema-jsonc.json",
33
"entry": ["src/index.ts!"],
4+
"ignore": ["src/types/utilities.ts"], // https://github.com/webpro-nl/knip/issues/996
45
"ignoreExportsUsedInFile": { "interface": true, "type": true },
56
"ignoreMembers": ["finish"], // https://github.com/webpro/knip/issues/414
67
"include": ["classMembers"],

src/types/utilities.ts

Lines changed: 55 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,22 @@ import {
3434
* ```ts
3535
* declare const type: ts.Type;
3636
*
37-
* for (const typePart of intersectionTypeParts(type)) {
37+
* for (const constituent of intersectionConstituents(type)) {
3838
* // ...
3939
* }
4040
* ```
4141
*/
42-
export function intersectionTypeParts(type: ts.Type): ts.Type[] {
42+
export function intersectionConstituents(type: ts.Type): ts.Type[] {
4343
return isIntersectionType(type) ? type.types : [type];
4444
}
4545

46+
/**
47+
* @deprecated Use {@link intersectionConstituents} instead.
48+
* @category Types - Utilities
49+
* ```
50+
*/
51+
export const intersectionTypeParts = intersectionConstituents;
52+
4653
/**
4754
* Determines whether a type is definitely falsy. This function doesn't unwrap union types.
4855
* @category Types - Utilities
@@ -97,7 +104,7 @@ export function isPropertyReadonlyInType(
97104
): boolean {
98105
let seenProperty = false;
99106
let seenReadonlySignature = false;
100-
for (const subType of unionTypeParts(type)) {
107+
for (const subType of unionConstituents(type)) {
101108
if (getPropertyOfType(subType, name) === undefined) {
102109
// property is not present in this part of the union -> check for readonly index signature
103110
const index =
@@ -179,15 +186,17 @@ export function isThenableType(
179186
node: ts.Node,
180187
type = typeChecker.getTypeAtLocation(node),
181188
): boolean {
182-
for (const typePart of unionTypeParts(typeChecker.getApparentType(type))) {
183-
const then = typePart.getProperty("then");
189+
for (const constituent of unionConstituents(
190+
typeChecker.getApparentType(type),
191+
)) {
192+
const then = constituent.getProperty("then");
184193
if (then === undefined) {
185194
continue;
186195
}
187196

188197
const thenType = typeChecker.getTypeOfSymbolAtLocation(then, node);
189-
for (const subTypePart of unionTypeParts(thenType)) {
190-
for (const signature of subTypePart.getCallSignatures()) {
198+
for (const subConstituent of unionConstituents(thenType)) {
199+
for (const signature of subConstituent.getCallSignatures()) {
191200
if (
192201
signature.parameters.length !== 0 &&
193202
isCallback(typeChecker, signature.parameters[0], node)
@@ -235,6 +244,26 @@ export function symbolHasReadonlyDeclaration(
235244
);
236245
}
237246

247+
/**
248+
* Get the intersection or union type parts of the given type.
249+
*
250+
* Note that this is a shallow collection: it only returns `type.types` or `[type]`.
251+
*
252+
* If the given type is not an intersection or union type, an array contain only that type will be returned.
253+
* @category Types - Utilities
254+
* @example
255+
* ```ts
256+
* declare const type: ts.Type;
257+
*
258+
* for (const constituent of typeConstituents(type)) {
259+
* // ...
260+
* }
261+
* ```
262+
*/
263+
export function typeConstituents(type: ts.Type): ts.Type[] {
264+
return isIntersectionType(type) || isUnionType(type) ? type.types : [type];
265+
}
266+
238267
/**
239268
* TS's `type.isLiteral()` is bugged before TS v5.0 and won't return `true` for
240269
* bigint literals. Use this function instead if you need to check for bigint
@@ -265,24 +294,10 @@ export function typeIsLiteral(type: ts.Type): type is ts.LiteralType {
265294
}
266295

267296
/**
268-
* Get the intersection or union type parts of the given type.
269-
*
270-
* Note that this is a shallow collection: it only returns `type.types` or `[type]`.
271-
*
272-
* If the given type is not an intersection or union type, an array contain only that type will be returned.
297+
* @deprecated Use {@link typeConstituents} instead.
273298
* @category Types - Utilities
274-
* @example
275-
* ```ts
276-
* declare const type: ts.Type;
277-
*
278-
* for (const typePart of intersectionTypeParts(type)) {
279-
* // ...
280-
* }
281-
* ```
282299
*/
283-
export function typeParts(type: ts.Type): ts.Type[] {
284-
return isIntersectionType(type) || isUnionType(type) ? type.types : [type];
285-
}
300+
export const typeParts = typeConstituents;
286301

287302
/**
288303
* Get the union type parts of the given type.
@@ -293,15 +308,21 @@ export function typeParts(type: ts.Type): ts.Type[] {
293308
* ```ts
294309
* declare const type: ts.Type;
295310
*
296-
* for (const typePart of unionTypeParts(type)) {
311+
* for (const constituent of unionConstituents(type)) {
297312
* // ...
298313
* }
299314
* ```
300315
*/
301-
export function unionTypeParts(type: ts.Type): ts.Type[] {
316+
export function unionConstituents(type: ts.Type): ts.Type[] {
302317
return isUnionType(type) ? type.types : [type];
303318
}
304319

320+
/**
321+
* @deprecated Use {@link unionConstituents} instead.
322+
* @category Types - Utilities
323+
*/
324+
export const unionTypeParts = unionConstituents;
325+
305326
function isCallback(
306327
typeChecker: ts.TypeChecker,
307328
param: ts.Symbol,
@@ -318,7 +339,7 @@ function isCallback(
318339
}
319340
}
320341

321-
for (const subType of unionTypeParts(type)) {
342+
for (const subType of unionConstituents(type)) {
322343
if (subType.getCallSignatures().length !== 0) {
323344
return true;
324345
}
@@ -396,22 +417,24 @@ function isReadonlyPropertyIntersection(
396417
name: ts.__String,
397418
typeChecker: ts.TypeChecker,
398419
) {
399-
const typeParts = isIntersectionType(type) ? type.types : [type];
400-
return typeParts.some((subType): boolean => {
401-
const prop = getPropertyOfType(subType, name);
420+
const constituents = intersectionConstituents(type);
421+
return constituents.some((constituent): boolean => {
422+
const prop = getPropertyOfType(constituent, name);
402423
if (prop === undefined) {
403424
return false;
404425
}
405426

406427
if (prop.flags & ts.SymbolFlags.Transient) {
407428
if (
408429
/^(?:[1-9]\d*|0)$/.test(name as string) &&
409-
isTupleTypeReference(subType)
430+
isTupleTypeReference(constituent)
410431
) {
411-
return subType.target.readonly;
432+
return constituent.target.readonly;
412433
}
413434

414-
switch (isReadonlyPropertyFromMappedType(subType, name, typeChecker)) {
435+
switch (
436+
isReadonlyPropertyFromMappedType(constituent, name, typeChecker)
437+
) {
415438
case false:
416439
return false;
417440
case true:

0 commit comments

Comments
 (0)