facebook/flow · error · Error
Unexpected function parameter ${param.type}
Error message
Unexpected function parameter ${param.type} What it means
Thrown by flow-api-translator while converting a TypeScript declaration AST into a Flow definition. When mapping a function signature's parameter list it handles only Identifier, ArrayPattern, and ObjectPattern parameters (plus a leading `this` Identifier and a trailing RestElement); any other parameter node type reaches the else branch and throws, naming the node type.
Source
Thrown at packages/flow-api-translator/src/TSDefToFlowDef.js:1023
} else if (
param.type === 'ArrayPattern' ||
param.type === 'ObjectPattern'
) {
return constructFlowNode<FlowESTree.FunctionTypeParam>({
type: 'FunctionTypeParam',
name: constructFlowNode<FlowESTree.Identifier>({
type: 'Identifier',
name: `$$param${i}$`,
optional: false,
typeAnnotation: null,
}),
optional: Boolean(param.optional),
typeAnnotation: Transform.TSTypeAnnotationOpt(
param.typeAnnotation?.typeAnnotation,
),
});
} else {
throw new Error(`Unexpected function parameter ${param.type}`);
}
}),
};
}
static TSImportType(
node: TSESTree.TSImportType,
): FlowESTree.TypeAnnotationType {
const source =
node.argument ??
(node.source == null
? null
: ({
type: 'TSLiteralType',
loc: node.source.loc,
literal: node.source,
} as TSESTree.TSLiteralType));
if (source == null) {View on GitHub (pinned to d1341dac89)
Solutions
- Update flow-api-translator to the latest version — newer versions handle more parameter node types
- Grep the input .d.ts for constructor parameter properties (`constructor(private|protected|public ...)`) and rewrite them as an explicit property plus a plain parameter, since the message names the offending node type
- If you build the TS AST yourself, normalize parameters to Identifier/ArrayPattern/ObjectPattern before calling the transform
- If the input is valid TypeScript, file an issue with the minimal .d.ts that reproduces it
Example fix
// before (input .d.ts)
declare class Foo {
constructor(private name: string): void;
}
// after (input .d.ts)
declare class Foo {
name: string;
constructor(name: string): void;
} Defensive patterns
Strategy: type-guard
Validate before calling
const SUPPORTED_PARAMS = new Set(['Identifier', 'ArrayPattern', 'ObjectPattern']);
function functionParamsSupported(fn: {
params: ReadonlyArray<{ type: string }>;
}): boolean {
return fn.params.every(
(p) =>
SUPPORTED_PARAMS.has(p.type) ||
// leading `this` and trailing rest params are handled specially
(p.type === 'Identifier') ,
);
}
// walk the TS AST and run functionParamsSupported on every function-ish
// node before handing the file to TSDefToFlowDef Type guard
function isSupportedParamType(
type: string,
): type is 'Identifier' | 'ArrayPattern' | 'ObjectPattern' {
return type === 'Identifier' || type === 'ArrayPattern' || type === 'ObjectPattern';
} Try / catch
try {
const flowDef = translateTSDefToFlowDef(tsAst);
} catch (err) {
if (err instanceof Error && err.message.startsWith('Unexpected function parameter')) {
// report the .d.ts path + the param type from the message, skip the file
report.skipped(file, err.message);
} else {
throw err;
}
} Prevention
- Avoid constructor parameter properties in published .d.ts files
- Pre-filter declaration files in CI by translating all of them in a smoke step
- Keep flow-api-translator updated alongside your TypeScript version
- When generating ASTs programmatically, emit plain Identifier parameters
When it happens
Trigger: Calling the TSDefToFlowDef transform (e.g. translating a .d.ts file to Flow defs) on a TS AST containing a function-type parameter that is not Identifier/ArrayPattern/ObjectPattern — for example a TSParameterProperty from `constructor(private x: string)` style signatures, an AssignmentPattern, or an unexpected node shape produced by a different parser or TypeScript version.
Common situations: Translating .d.ts files that use constructor parameter properties; declarations generated by TypeScript versions whose AST shapes the translator does not know; hand-built or post-processed ASTs passed directly to the transform; translator and TypeScript versions out of sync.
Related errors
- updatePendingStatements: Variable for dependency "${dep}" no
- updatePendingStatements: Variable parent of "${dep}" not fou
- Flow check failed!
- Flow version ${version} doesn't support 'flow lsp'. Please u
- Unsupported .flowconfig option `log.file`. The VS Code exten
AI-assisted analysis of facebook/flow@d1341dac89 (2026-08-17).
Data as JSON: /api/errors/0f695d497dcff05c.
Report an issue: GitHub.