mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Error on template tag inside callback/overload/typedef tag (#54118)
This commit is contained in:
@@ -6592,6 +6592,10 @@
|
||||
"category": "Error",
|
||||
"code": 8038
|
||||
},
|
||||
"A JSDoc '@template' tag may not follow a '@typedef', '@callback', or '@overload' tag": {
|
||||
"category": "Error",
|
||||
"code": 8039
|
||||
},
|
||||
|
||||
"Declaration emit for this file requires using private name '{0}'. An explicit type annotation may unblock declaration emit.": {
|
||||
"category": "Error",
|
||||
|
||||
+20
-9
@@ -9140,12 +9140,15 @@ namespace Parser {
|
||||
function parseNestedTypeLiteral(typeExpression: JSDocTypeExpression | undefined, name: EntityName, target: PropertyLikeParse, indent: number) {
|
||||
if (typeExpression && isObjectOrObjectArrayTypeReference(typeExpression.type)) {
|
||||
const pos = getNodePos();
|
||||
let child: JSDocPropertyLikeTag | JSDocTypeTag | false;
|
||||
let child: JSDocPropertyLikeTag | JSDocTypeTag | JSDocTemplateTag | false;
|
||||
let children: JSDocPropertyLikeTag[] | undefined;
|
||||
while (child = tryParse(() => parseChildParameterOrPropertyTag(target, indent, name))) {
|
||||
if (child.kind === SyntaxKind.JSDocParameterTag || child.kind === SyntaxKind.JSDocPropertyTag) {
|
||||
children = append(children, child);
|
||||
}
|
||||
else if (child.kind === SyntaxKind.JSDocTemplateTag) {
|
||||
parseErrorAtRange(child.tagName, Diagnostics.A_JSDoc_template_tag_may_not_follow_a_typedef_callback_or_overload_tag);
|
||||
}
|
||||
}
|
||||
if (children) {
|
||||
const literal = finishNode(factory.createJSDocTypeLiteral(children, typeExpression.type.kind === SyntaxKind.ArrayType), pos);
|
||||
@@ -9291,11 +9294,14 @@ namespace Parser {
|
||||
|
||||
let end: number | undefined;
|
||||
if (!typeExpression || isObjectOrObjectArrayTypeReference(typeExpression.type)) {
|
||||
let child: JSDocTypeTag | JSDocPropertyTag | false;
|
||||
let child: JSDocTypeTag | JSDocPropertyTag | JSDocTemplateTag | false;
|
||||
let childTypeTag: JSDocTypeTag | undefined;
|
||||
let jsDocPropertyTags: JSDocPropertyTag[] | undefined;
|
||||
let hasChildren = false;
|
||||
while (child = tryParse(() => parseChildPropertyTag(indent))) {
|
||||
if (child.kind === SyntaxKind.JSDocTemplateTag) {
|
||||
break;
|
||||
}
|
||||
hasChildren = true;
|
||||
if (child.kind === SyntaxKind.JSDocTypeTag) {
|
||||
if (childTypeTag) {
|
||||
@@ -9359,12 +9365,15 @@ namespace Parser {
|
||||
return typeNameOrNamespaceName;
|
||||
}
|
||||
|
||||
|
||||
function parseCallbackTagParameters(indent: number) {
|
||||
const pos = getNodePos();
|
||||
let child: JSDocParameterTag | false;
|
||||
let child: JSDocParameterTag | JSDocTemplateTag | false;
|
||||
let parameters;
|
||||
while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.CallbackParameter, indent) as JSDocParameterTag)) {
|
||||
while (child = tryParse(() => parseChildParameterOrPropertyTag(PropertyLikeParse.CallbackParameter, indent) as JSDocParameterTag | JSDocTemplateTag)) {
|
||||
if (child.kind === SyntaxKind.JSDocTemplateTag) {
|
||||
parseErrorAtRange(child.tagName, Diagnostics.A_JSDoc_template_tag_may_not_follow_a_typedef_callback_or_overload_tag);
|
||||
break;
|
||||
}
|
||||
parameters = append(parameters, child);
|
||||
}
|
||||
return createNodeArray(parameters || [], pos);
|
||||
@@ -9420,10 +9429,10 @@ namespace Parser {
|
||||
}
|
||||
|
||||
function parseChildPropertyTag(indent: number) {
|
||||
return parseChildParameterOrPropertyTag(PropertyLikeParse.Property, indent) as JSDocTypeTag | JSDocPropertyTag | false;
|
||||
return parseChildParameterOrPropertyTag(PropertyLikeParse.Property, indent) as JSDocTypeTag | JSDocPropertyTag | JSDocTemplateTag | false;
|
||||
}
|
||||
|
||||
function parseChildParameterOrPropertyTag(target: PropertyLikeParse, indent: number, name?: EntityName): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | false {
|
||||
function parseChildParameterOrPropertyTag(target: PropertyLikeParse, indent: number, name?: EntityName): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | JSDocTemplateTag | false {
|
||||
let canParseTag = true;
|
||||
let seenAsterisk = false;
|
||||
while (true) {
|
||||
@@ -9459,13 +9468,13 @@ namespace Parser {
|
||||
}
|
||||
}
|
||||
|
||||
function tryParseChildTag(target: PropertyLikeParse, indent: number): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | false {
|
||||
function tryParseChildTag(target: PropertyLikeParse, indent: number): JSDocTypeTag | JSDocPropertyTag | JSDocParameterTag | JSDocTemplateTag | false {
|
||||
Debug.assert(token() === SyntaxKind.AtToken);
|
||||
const start = scanner.getTokenFullStart();
|
||||
nextTokenJSDoc();
|
||||
|
||||
const tagName = parseJSDocIdentifierName();
|
||||
skipWhitespace();
|
||||
const indentText = skipWhitespaceOrAsterisk();
|
||||
let t: PropertyLikeParse;
|
||||
switch (tagName.escapedText) {
|
||||
case "type":
|
||||
@@ -9479,6 +9488,8 @@ namespace Parser {
|
||||
case "param":
|
||||
t = PropertyLikeParse.Parameter | PropertyLikeParse.CallbackParameter;
|
||||
break;
|
||||
case "template":
|
||||
return parseTemplateTag(start, tagName, indent, indentText);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
error TS-1: Pre-emit (11) and post-emit (13) diagnostic counts do not match! This can indicate that a semantic _error_ was added by the emit resolver - such an error may not be reflected on the command line or in the editor, but may be captured in a baseline here!
|
||||
tests/cases/conformance/jsdoc/templateInsideCallback.js(2,13): error TS8021: JSDoc '@typedef' tag should either have a type annotation or be followed by '@property' or '@member' tags.
|
||||
tests/cases/conformance/jsdoc/templateInsideCallback.js(9,5): error TS8039: A JSDoc '@template' tag may not follow a '@typedef', '@callback', or '@overload' tag
|
||||
tests/cases/conformance/jsdoc/templateInsideCallback.js(10,12): error TS2304: Cannot find name 'T'.
|
||||
tests/cases/conformance/jsdoc/templateInsideCallback.js(15,11): error TS2315: Type 'Call' is not generic.
|
||||
tests/cases/conformance/jsdoc/templateInsideCallback.js(17,18): error TS7006: Parameter 'x' implicitly has an 'any' type.
|
||||
tests/cases/conformance/jsdoc/templateInsideCallback.js(23,5): error TS8039: A JSDoc '@template' tag may not follow a '@typedef', '@callback', or '@overload' tag
|
||||
tests/cases/conformance/jsdoc/templateInsideCallback.js(30,5): error TS8039: A JSDoc '@template' tag may not follow a '@typedef', '@callback', or '@overload' tag
|
||||
tests/cases/conformance/jsdoc/templateInsideCallback.js(32,12): error TS2304: Cannot find name 'T'.
|
||||
tests/cases/conformance/jsdoc/templateInsideCallback.js(33,16): error TS2304: Cannot find name 'T'.
|
||||
tests/cases/conformance/jsdoc/templateInsideCallback.js(38,5): error TS8039: A JSDoc '@template' tag may not follow a '@typedef', '@callback', or '@overload' tag
|
||||
tests/cases/conformance/jsdoc/templateInsideCallback.js(39,12): error TS2304: Cannot find name 'T'.
|
||||
|
||||
|
||||
!!! error TS-1: Pre-emit (11) and post-emit (13) diagnostic counts do not match! This can indicate that a semantic _error_ was added by the emit resolver - such an error may not be reflected on the command line or in the editor, but may be captured in a baseline here!
|
||||
!!! related TS-1: The excess diagnostics are:
|
||||
!!! related TS7012 tests/cases/conformance/jsdoc/templateInsideCallback.js:29:5: This overload implicitly returns the type 'any' because it lacks a return type annotation.
|
||||
!!! related TS7012 tests/cases/conformance/jsdoc/templateInsideCallback.js:37:5: This overload implicitly returns the type 'any' because it lacks a return type annotation.
|
||||
==== tests/cases/conformance/jsdoc/templateInsideCallback.js (11 errors) ====
|
||||
/**
|
||||
* @typedef Oops
|
||||
~~~~
|
||||
!!! error TS8021: JSDoc '@typedef' tag should either have a type annotation or be followed by '@property' or '@member' tags.
|
||||
* @template T
|
||||
* @property {T} a
|
||||
* @property {T} b
|
||||
*/
|
||||
/**
|
||||
* @callback Call
|
||||
* @template T
|
||||
~~~~~~~~
|
||||
!!! error TS8039: A JSDoc '@template' tag may not follow a '@typedef', '@callback', or '@overload' tag
|
||||
* @param {T} x
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'T'.
|
||||
* @returns {T}
|
||||
*/
|
||||
/**
|
||||
* @template T
|
||||
* @type {Call<T>}
|
||||
~~~~~~~
|
||||
!!! error TS2315: Type 'Call' is not generic.
|
||||
*/
|
||||
const identity = x => x;
|
||||
~
|
||||
!!! error TS7006: Parameter 'x' implicitly has an 'any' type.
|
||||
|
||||
/**
|
||||
* @typedef Nested
|
||||
* @property {Object} oh
|
||||
* @property {number} oh.no
|
||||
* @template T
|
||||
~~~~~~~~
|
||||
!!! error TS8039: A JSDoc '@template' tag may not follow a '@typedef', '@callback', or '@overload' tag
|
||||
* @property {string} oh.noooooo
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @overload
|
||||
* @template T
|
||||
~~~~~~~~
|
||||
!!! error TS8039: A JSDoc '@template' tag may not follow a '@typedef', '@callback', or '@overload' tag
|
||||
* @template U
|
||||
* @param {T[]} array
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'T'.
|
||||
* @param {(x: T) => U[]} iterable
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'T'.
|
||||
* @returns {U[]}
|
||||
*/
|
||||
/**
|
||||
* @overload
|
||||
* @template T
|
||||
~~~~~~~~
|
||||
!!! error TS8039: A JSDoc '@template' tag may not follow a '@typedef', '@callback', or '@overload' tag
|
||||
* @param {T[][]} array
|
||||
~
|
||||
!!! error TS2304: Cannot find name 'T'.
|
||||
* @returns {T[]}
|
||||
*/
|
||||
/**
|
||||
* @param {unknown[]} array
|
||||
* @param {(x: unknown) => unknown} iterable
|
||||
* @returns {unknown[]}
|
||||
*/
|
||||
function flatMap(array, iterable = identity) {
|
||||
/** @type {unknown[]} */
|
||||
const result = [];
|
||||
for (let i = 0; i < array.length; i += 1) {
|
||||
result.push(.../** @type {unknown[]} */(iterable(array[i])));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,141 @@
|
||||
//// [templateInsideCallback.js]
|
||||
/**
|
||||
* @typedef Oops
|
||||
* @template T
|
||||
* @property {T} a
|
||||
* @property {T} b
|
||||
*/
|
||||
/**
|
||||
* @callback Call
|
||||
* @template T
|
||||
* @param {T} x
|
||||
* @returns {T}
|
||||
*/
|
||||
/**
|
||||
* @template T
|
||||
* @type {Call<T>}
|
||||
*/
|
||||
const identity = x => x;
|
||||
|
||||
/**
|
||||
* @typedef Nested
|
||||
* @property {Object} oh
|
||||
* @property {number} oh.no
|
||||
* @template T
|
||||
* @property {string} oh.noooooo
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @overload
|
||||
* @template T
|
||||
* @template U
|
||||
* @param {T[]} array
|
||||
* @param {(x: T) => U[]} iterable
|
||||
* @returns {U[]}
|
||||
*/
|
||||
/**
|
||||
* @overload
|
||||
* @template T
|
||||
* @param {T[][]} array
|
||||
* @returns {T[]}
|
||||
*/
|
||||
/**
|
||||
* @param {unknown[]} array
|
||||
* @param {(x: unknown) => unknown} iterable
|
||||
* @returns {unknown[]}
|
||||
*/
|
||||
function flatMap(array, iterable = identity) {
|
||||
/** @type {unknown[]} */
|
||||
const result = [];
|
||||
for (let i = 0; i < array.length; i += 1) {
|
||||
result.push(.../** @type {unknown[]} */(iterable(array[i])));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//// [templateInsideCallback.js]
|
||||
"use strict";
|
||||
/**
|
||||
* @typedef Oops
|
||||
* @template T
|
||||
* @property {T} a
|
||||
* @property {T} b
|
||||
*/
|
||||
/**
|
||||
* @callback Call
|
||||
* @template T
|
||||
* @param {T} x
|
||||
* @returns {T}
|
||||
*/
|
||||
/**
|
||||
* @template T
|
||||
* @type {Call<T>}
|
||||
*/
|
||||
var identity = function (x) { return x; };
|
||||
/**
|
||||
* @typedef Nested
|
||||
* @property {Object} oh
|
||||
* @property {number} oh.no
|
||||
* @template T
|
||||
* @property {string} oh.noooooo
|
||||
*/
|
||||
/**
|
||||
* @overload
|
||||
* @template T
|
||||
* @template U
|
||||
* @param {T[]} array
|
||||
* @param {(x: T) => U[]} iterable
|
||||
* @returns {U[]}
|
||||
*/
|
||||
/**
|
||||
* @overload
|
||||
* @template T
|
||||
* @param {T[][]} array
|
||||
* @returns {T[]}
|
||||
*/
|
||||
/**
|
||||
* @param {unknown[]} array
|
||||
* @param {(x: unknown) => unknown} iterable
|
||||
* @returns {unknown[]}
|
||||
*/
|
||||
function flatMap(array, iterable) {
|
||||
if (iterable === void 0) { iterable = identity; }
|
||||
/** @type {unknown[]} */
|
||||
var result = [];
|
||||
for (var i = 0; i < array.length; i += 1) {
|
||||
result.push.apply(result, /** @type {unknown[]} */ (iterable(array[i])));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//// [templateInsideCallback.d.ts]
|
||||
declare function flatMap<U>(): any;
|
||||
declare function flatMap(): any;
|
||||
/**
|
||||
* @typedef Oops
|
||||
* @template T
|
||||
* @property {T} a
|
||||
* @property {T} b
|
||||
*/
|
||||
/**
|
||||
* @callback Call
|
||||
* @template T
|
||||
* @param {T} x
|
||||
* @returns {T}
|
||||
*/
|
||||
/**
|
||||
* @template T
|
||||
* @type {Call<T>}
|
||||
*/
|
||||
declare const identity: any;
|
||||
type Nested = {
|
||||
oh: {
|
||||
no: number;
|
||||
noooooo: string;
|
||||
};
|
||||
};
|
||||
type Oops = any;
|
||||
type Call = () => any;
|
||||
@@ -0,0 +1,80 @@
|
||||
=== tests/cases/conformance/jsdoc/templateInsideCallback.js ===
|
||||
/**
|
||||
* @typedef Oops
|
||||
* @template T
|
||||
* @property {T} a
|
||||
* @property {T} b
|
||||
*/
|
||||
/**
|
||||
* @callback Call
|
||||
* @template T
|
||||
* @param {T} x
|
||||
* @returns {T}
|
||||
*/
|
||||
/**
|
||||
* @template T
|
||||
* @type {Call<T>}
|
||||
*/
|
||||
const identity = x => x;
|
||||
>identity : Symbol(identity, Decl(templateInsideCallback.js, 16, 5))
|
||||
>x : Symbol(x, Decl(templateInsideCallback.js, 16, 16))
|
||||
>x : Symbol(x, Decl(templateInsideCallback.js, 16, 16))
|
||||
|
||||
/**
|
||||
* @typedef Nested
|
||||
* @property {Object} oh
|
||||
* @property {number} oh.no
|
||||
* @template T
|
||||
* @property {string} oh.noooooo
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @overload
|
||||
* @template T
|
||||
* @template U
|
||||
* @param {T[]} array
|
||||
* @param {(x: T) => U[]} iterable
|
||||
* @returns {U[]}
|
||||
*/
|
||||
/**
|
||||
* @overload
|
||||
* @template T
|
||||
* @param {T[][]} array
|
||||
* @returns {T[]}
|
||||
*/
|
||||
/**
|
||||
* @param {unknown[]} array
|
||||
* @param {(x: unknown) => unknown} iterable
|
||||
* @returns {unknown[]}
|
||||
*/
|
||||
function flatMap(array, iterable = identity) {
|
||||
>flatMap : Symbol(flatMap, Decl(templateInsideCallback.js, 16, 24))
|
||||
>array : Symbol(array, Decl(templateInsideCallback.js, 46, 17))
|
||||
>iterable : Symbol(iterable, Decl(templateInsideCallback.js, 46, 23))
|
||||
>identity : Symbol(identity, Decl(templateInsideCallback.js, 16, 5))
|
||||
|
||||
/** @type {unknown[]} */
|
||||
const result = [];
|
||||
>result : Symbol(result, Decl(templateInsideCallback.js, 48, 7))
|
||||
|
||||
for (let i = 0; i < array.length; i += 1) {
|
||||
>i : Symbol(i, Decl(templateInsideCallback.js, 49, 10))
|
||||
>i : Symbol(i, Decl(templateInsideCallback.js, 49, 10))
|
||||
>array.length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
|
||||
>array : Symbol(array, Decl(templateInsideCallback.js, 46, 17))
|
||||
>length : Symbol(Array.length, Decl(lib.es5.d.ts, --, --))
|
||||
>i : Symbol(i, Decl(templateInsideCallback.js, 49, 10))
|
||||
|
||||
result.push(.../** @type {unknown[]} */(iterable(array[i])));
|
||||
>result.push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
|
||||
>result : Symbol(result, Decl(templateInsideCallback.js, 48, 7))
|
||||
>push : Symbol(Array.push, Decl(lib.es5.d.ts, --, --))
|
||||
>iterable : Symbol(iterable, Decl(templateInsideCallback.js, 46, 23))
|
||||
>array : Symbol(array, Decl(templateInsideCallback.js, 46, 17))
|
||||
>i : Symbol(i, Decl(templateInsideCallback.js, 49, 10))
|
||||
}
|
||||
return result;
|
||||
>result : Symbol(result, Decl(templateInsideCallback.js, 48, 7))
|
||||
}
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
=== tests/cases/conformance/jsdoc/templateInsideCallback.js ===
|
||||
/**
|
||||
* @typedef Oops
|
||||
* @template T
|
||||
* @property {T} a
|
||||
* @property {T} b
|
||||
*/
|
||||
/**
|
||||
* @callback Call
|
||||
* @template T
|
||||
* @param {T} x
|
||||
* @returns {T}
|
||||
*/
|
||||
/**
|
||||
* @template T
|
||||
* @type {Call<T>}
|
||||
*/
|
||||
const identity = x => x;
|
||||
>identity : any
|
||||
>x => x : <T>(x: any) => any
|
||||
>x : any
|
||||
>x : any
|
||||
|
||||
/**
|
||||
* @typedef Nested
|
||||
* @property {Object} oh
|
||||
* @property {number} oh.no
|
||||
* @template T
|
||||
* @property {string} oh.noooooo
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @overload
|
||||
* @template T
|
||||
* @template U
|
||||
* @param {T[]} array
|
||||
* @param {(x: T) => U[]} iterable
|
||||
* @returns {U[]}
|
||||
*/
|
||||
/**
|
||||
* @overload
|
||||
* @template T
|
||||
* @param {T[][]} array
|
||||
* @returns {T[]}
|
||||
*/
|
||||
/**
|
||||
* @param {unknown[]} array
|
||||
* @param {(x: unknown) => unknown} iterable
|
||||
* @returns {unknown[]}
|
||||
*/
|
||||
function flatMap(array, iterable = identity) {
|
||||
>flatMap : { <U>(): any; (): any; }
|
||||
>array : unknown[]
|
||||
>iterable : (x: unknown) => unknown
|
||||
>identity : any
|
||||
|
||||
/** @type {unknown[]} */
|
||||
const result = [];
|
||||
>result : unknown[]
|
||||
>[] : never[]
|
||||
|
||||
for (let i = 0; i < array.length; i += 1) {
|
||||
>i : number
|
||||
>0 : 0
|
||||
>i < array.length : boolean
|
||||
>i : number
|
||||
>array.length : number
|
||||
>array : unknown[]
|
||||
>length : number
|
||||
>i += 1 : number
|
||||
>i : number
|
||||
>1 : 1
|
||||
|
||||
result.push(.../** @type {unknown[]} */(iterable(array[i])));
|
||||
>result.push(.../** @type {unknown[]} */(iterable(array[i]))) : number
|
||||
>result.push : (...items: unknown[]) => number
|
||||
>result : unknown[]
|
||||
>push : (...items: unknown[]) => number
|
||||
>.../** @type {unknown[]} */(iterable(array[i])) : unknown
|
||||
>(iterable(array[i])) : unknown[]
|
||||
>iterable(array[i]) : unknown
|
||||
>iterable : (x: unknown) => unknown
|
||||
>array[i] : unknown
|
||||
>array : unknown[]
|
||||
>i : number
|
||||
}
|
||||
return result;
|
||||
>result : unknown[]
|
||||
}
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
// @checkJs: true
|
||||
// @strict: true
|
||||
// @outDir: dist/
|
||||
// @declaration: true
|
||||
// @filename: templateInsideCallback.js
|
||||
/**
|
||||
* @typedef Oops
|
||||
* @template T
|
||||
* @property {T} a
|
||||
* @property {T} b
|
||||
*/
|
||||
/**
|
||||
* @callback Call
|
||||
* @template T
|
||||
* @param {T} x
|
||||
* @returns {T}
|
||||
*/
|
||||
/**
|
||||
* @template T
|
||||
* @type {Call<T>}
|
||||
*/
|
||||
const identity = x => x;
|
||||
|
||||
/**
|
||||
* @typedef Nested
|
||||
* @property {Object} oh
|
||||
* @property {number} oh.no
|
||||
* @template T
|
||||
* @property {string} oh.noooooo
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @overload
|
||||
* @template T
|
||||
* @template U
|
||||
* @param {T[]} array
|
||||
* @param {(x: T) => U[]} iterable
|
||||
* @returns {U[]}
|
||||
*/
|
||||
/**
|
||||
* @overload
|
||||
* @template T
|
||||
* @param {T[][]} array
|
||||
* @returns {T[]}
|
||||
*/
|
||||
/**
|
||||
* @param {unknown[]} array
|
||||
* @param {(x: unknown) => unknown} iterable
|
||||
* @returns {unknown[]}
|
||||
*/
|
||||
function flatMap(array, iterable = identity) {
|
||||
/** @type {unknown[]} */
|
||||
const result = [];
|
||||
for (let i = 0; i < array.length; i += 1) {
|
||||
result.push(.../** @type {unknown[]} */(iterable(array[i])));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
Reference in New Issue
Block a user