meaningAt
Which meaning of a name an identifier uses. Usually that's its position, except that typeof x names a
value even though it sits in a type, and so does a computed key (readonly [evaluate]: …, evaluate a unique
symbol beside a type of that name).
import { isTypePosition } from "#codebase/tcmts/core/canonicalize"; import type { Meaning } from "#codebase/tcmts/core/canonicalize"; import { isComputedPropertyName as ts_isComputedPropertyName, isPropertyAccessExpression as ts_isPropertyAccessExpression, isQualifiedName as ts_isQualifiedName, isTypeQueryNode as ts_isTypeQueryNode, } from "typescript/ast"; import type { Node as ts_Node } from "typescript/ast"; export function meaningAt(id: ts_Node): Meaning { let key: ts_Node = id; while (key.parent && ts_isPropertyAccessExpression(key.parent) && key.parent.expression === key) key = key.parent; if (key.parent && ts_isComputedPropertyName(key.parent)) return "value"; for ( let n: ts_Node = id; n.parent && (ts_isQualifiedName(n.parent) || ts_isTypeQueryNode(n.parent)); n = n.parent ) { if (ts_isTypeQueryNode(n.parent)) return "value"; } return isTypePosition(id) ? "type" : "value"; }