{"id":14438,"library":"ast-types-flow","title":"Flow Types for JavaScript AST","description":"ast-types-flow provides Flow type definitions specifically tailored for JavaScript Abstract Syntax Trees (ASTs), designed to integrate with AST structures produced by parsers compatible with `benjamn/ast-types`. Published as version 0.0.8, the project appears to be abandoned, with its last update several years ago, reflecting the broader shift in the JavaScript ecosystem's preference from Flow to TypeScript for static typing. The library employs a distinctive method, utilizing special comments like `// extends Node` to define type hierarchies, which are then processed by a custom transform into disjoint union types. This approach aims to facilitate robust type refinement for diverse AST nodes, though it often requires duplicating complete type definitions and introducing unique `_Foo: void` fields to satisfy Flow's structural uniqueness requirements for disjoint unions. It was intended for static analysis of ASTs within Flow-typed projects.","status":"abandoned","version":"0.0.8","language":"javascript","source_language":"en","source_url":"https://github.com/kyldvs/ast-types-flow","tags":["javascript","flow","ast"],"install":[{"cmd":"npm install ast-types-flow","lang":"bash","label":"npm"},{"cmd":"yarn add ast-types-flow","lang":"bash","label":"yarn"},{"cmd":"pnpm add ast-types-flow","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Provides the underlying AST structure for which these Flow types are generated. It's a conceptual and likely a peer dependency, not a direct runtime dependency of the types themselves.","package":"ast-types","optional":true}],"imports":[{"note":"Flow type imports use `import type`. CommonJS `require` does not handle Flow types directly.","wrong":"const Node = require('ast-types-flow');","symbol":"Node","correct":"import type { Node } from 'ast-types-flow';"},{"note":"Always use `import type` for Flow type declarations. Named imports without `type` are for JavaScript values.","wrong":"import { Identifier } from 'ast-types-flow';","symbol":"Identifier","correct":"import type { Identifier } from 'ast-types-flow';"},{"note":"The package exports only Flow types, not runtime JavaScript modules. CommonJS `require` is not applicable for types.","wrong":"const { ClassDeclaration } = require('ast-types-flow');","symbol":"ClassDeclaration","correct":"import type { ClassDeclaration } from 'ast-types-flow';"}],"quickstart":{"code":"/* @flow */\n\nimport type { Node, Identifier, ClassDeclaration, FunctionDeclaration, FunctionExpression, Literal } from 'ast-types-flow';\n\n/**\n * Safely extracts the name from various AST node types.\n * Handles cases where IDs might be null or properties might not exist.\n * @param {Node} node - The AST node to inspect.\n * @returns {string} The name of the node or 'Unknown'.\n */\nfunction getName(node: Node): string {\n  switch (node.type) {\n    case 'Identifier':\n      return node.name; // 'Identifier' nodes reliably have a 'name' property.\n\n    case 'ClassDeclaration':\n      // Flow would flag 'node.id' as potentially null. Refinement is needed.\n      if (node.id) {\n        return node.id.name;\n      }\n      return 'AnonymousClass'; // Handle the nullable case explicitly.\n\n    case 'FunctionDeclaration':\n      // Assuming 'id' is always present for 'FunctionDeclaration' in this context.\n      return node.id.name;\n\n    case 'FunctionExpression':\n      // 'FunctionExpression' can be anonymous; 'id' might be null.\n      if (node.id) {\n        return node.id.name;\n      } else {\n        return 'AnonymousFunction';\n      }\n\n    case 'Literal':\n      // 'Literal' nodes do not have a 'name' property. Flow would error here.\n      if (typeof node.value === 'string' || typeof node.value === 'number') {\n        return String(node.value); // Return the literal's value instead.\n      }\n      return 'LiteralValue';\n\n    default:\n      return 'UnknownNode';\n  }\n}\n\n// Example usage (not runnable without an actual AST node)\nconst myIdentifier: Identifier = { type: 'Identifier', name: 'foo' };\nconst myClassDecl: ClassDeclaration = { type: 'ClassDeclaration', id: { type: 'Identifier', name: 'MyClass' }, body: { type: 'BlockStatement', body: [] } };\nconst myLiteral: Literal = { type: 'Literal', value: 123, raw: '123' };\n\nconsole.log(getName(myIdentifier)); // Expected: foo\nconsole.log(getName(myClassDecl));  // Expected: MyClass\nconsole.log(getName(myLiteral));    // Expected: 123","lang":"javascript","description":"Demonstrates importing Flow types for AST nodes and using them in a type-checked function to safely extract names, handling potential nulls and missing properties according to Flow's rules."},"warnings":[{"fix":"Consider using TypeScript with `@types/estree` or `@types/babel__types` for AST typing in modern JavaScript projects, or migrate existing Flow projects to TypeScript.","message":"The `ast-types-flow` package is largely abandoned (last updated ~8-10 years ago) and targets Flow, a static type checker that has seen significantly reduced adoption in favor of TypeScript. It is not recommended for new projects.","severity":"deprecated","affected_versions":">=0.0.1"},{"fix":"Ensure the necessary transform is applied in your build pipeline if you are using this library. Be aware that this approach is unique to this library and not standard Flow syntax.","message":"The library utilizes a non-standard syntax (comments like `// extends Node`) for defining type hierarchies, requiring a specific transform step to generate the final Flow types. This can complicate tooling integration and understanding.","severity":"gotcha","affected_versions":">=0.0.1"},{"fix":"This is an internal implementation detail of the library to work around Flow's limitations at the time. There is no direct fix for users other than being aware of this behavior.","message":"To ensure Flow's disjoint union refinement works correctly, the library generates types with duplicated complete definitions and adds private `_Foo: void` fields. This can lead to verbose type definitions and might be confusing.","severity":"gotcha","affected_versions":">=0.0.1"},{"fix":"Always implement explicit null/undefined checks (e.g., `if (node.id)`) or type guards when accessing potentially nullable properties, and consult the AST specification for property existence on specific node types.","message":"Flow type definitions for ASTs often expose properties that can be `null` or `undefined` (e.g., `id` on `ClassDeclaration` or `FunctionExpression`) or that simply do not exist on certain node types (e.g., `name` on `Literal`). Direct access without checks will result in Flow errors.","severity":"gotcha","affected_versions":">=0.0.1"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Add a null check for the `id` property before attempting to access its `name`: `if (node.id) { return node.id.name; }`","cause":"Attempting to access a property on an AST node's `id` property, when `id` is defined as nullable (e.g., for anonymous functions or classes without explicit identifiers).","error":"Cannot get `node.id.name` because `node.id` is `null` or `undefined`."},{"fix":"Consult the AST specification for the correct properties available on the specific node type you are working with. For `Literal` nodes, you likely want `node.value`.","cause":"Attempting to access a property (like `name`) that does not exist on a specific AST node type (e.g., `Literal` nodes have a `value` property, not `name`).","error":"Property `name` is missing in `Literal` [1]."},{"fix":"Ensure you are using `import type { ... } from 'ast-types-flow';` for Flow type imports. The package is not meant for runtime consumption.","cause":"Attempting to use `require()` or a non-type `import` for `ast-types-flow`, which is exclusively a type definition package and does not provide runtime JavaScript modules.","error":"Error: `ast-types-flow` cannot be found or is not a module."}],"ecosystem":"npm"}