Skip to content

Commit 847d787

Browse files
committed
fix: support type annotation on rest parameters in arrow function
Fixes sveltejs/svelte#15293
1 parent 0eb48d9 commit 847d787

File tree

4 files changed

+214
-0
lines changed

4 files changed

+214
-0
lines changed

.changeset/swift-regions-know.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/acorn-typescript': patch
3+
---
4+
5+
fix: support type annotation on rest parameters in arrow function

__test__/__snapshot__/arrow-function/type.ts

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,6 +1695,200 @@ const ArrowFunctionTypeSnapshot = {
16951695
}
16961696
],
16971697
sourceType: 'module'
1698+
},
1699+
RestParameter: {
1700+
type: 'Program',
1701+
start: 0,
1702+
end: 30,
1703+
loc: { start: { line: 1, column: 0, index: 0 }, end: { line: 1, column: 30, index: 30 } },
1704+
body: [
1705+
{
1706+
type: 'VariableDeclaration',
1707+
start: 0,
1708+
end: 30,
1709+
loc: { start: { line: 1, column: 0, index: 0 }, end: { line: 1, column: 30, index: 30 } },
1710+
declarations: [
1711+
{
1712+
type: 'VariableDeclarator',
1713+
start: 6,
1714+
end: 30,
1715+
loc: {
1716+
start: { line: 1, column: 6, index: 6 },
1717+
end: { line: 1, column: 30, index: 30 }
1718+
},
1719+
id: {
1720+
type: 'Identifier',
1721+
start: 6,
1722+
end: 7,
1723+
loc: {
1724+
start: { line: 1, column: 6, index: 6 },
1725+
end: { line: 1, column: 7, index: 7 }
1726+
},
1727+
name: 'f'
1728+
},
1729+
init: {
1730+
type: 'ArrowFunctionExpression',
1731+
start: 10,
1732+
end: 30,
1733+
loc: {
1734+
start: { line: 1, column: 10, index: 10 },
1735+
end: { line: 1, column: 30, index: 30 }
1736+
},
1737+
id: null,
1738+
expression: false,
1739+
generator: false,
1740+
async: false,
1741+
params: [
1742+
{
1743+
type: 'RestElement',
1744+
start: 11,
1745+
loc: { start: { line: 1, column: 11, index: 11 }, end: 23 },
1746+
argument: {
1747+
type: 'Identifier',
1748+
start: 14,
1749+
end: 18,
1750+
loc: {
1751+
start: { line: 1, column: 14, index: 14 },
1752+
end: { line: 1, column: 18, index: 18 }
1753+
},
1754+
name: 'args'
1755+
},
1756+
typeAnnotation: {
1757+
type: 'TSTypeAnnotation',
1758+
start: 18,
1759+
end: 23,
1760+
loc: {
1761+
start: { line: 1, column: 18, index: 18 },
1762+
end: { line: 1, column: 23, index: 23 }
1763+
},
1764+
typeAnnotation: {
1765+
type: 'TSAnyKeyword',
1766+
start: 20,
1767+
end: 23,
1768+
loc: {
1769+
start: { line: 1, column: 20, index: 20 },
1770+
end: { line: 1, column: 23, index: 23 }
1771+
}
1772+
}
1773+
}
1774+
}
1775+
],
1776+
body: {
1777+
type: 'BlockStatement',
1778+
start: 28,
1779+
end: 30,
1780+
loc: {
1781+
start: { line: 1, column: 28, index: 28 },
1782+
end: { line: 1, column: 30, index: 30 }
1783+
},
1784+
body: []
1785+
}
1786+
}
1787+
}
1788+
],
1789+
kind: 'const'
1790+
}
1791+
],
1792+
sourceType: 'module'
1793+
},
1794+
AsyncRestParameter: {
1795+
type: 'Program',
1796+
start: 0,
1797+
end: 36,
1798+
loc: { start: { line: 1, column: 0, index: 0 }, end: { line: 1, column: 36, index: 36 } },
1799+
body: [
1800+
{
1801+
type: 'VariableDeclaration',
1802+
start: 0,
1803+
end: 36,
1804+
loc: { start: { line: 1, column: 0, index: 0 }, end: { line: 1, column: 36, index: 36 } },
1805+
declarations: [
1806+
{
1807+
type: 'VariableDeclarator',
1808+
start: 6,
1809+
end: 36,
1810+
loc: {
1811+
start: { line: 1, column: 6, index: 6 },
1812+
end: { line: 1, column: 36, index: 36 }
1813+
},
1814+
id: {
1815+
type: 'Identifier',
1816+
start: 6,
1817+
end: 7,
1818+
loc: {
1819+
start: { line: 1, column: 6, index: 6 },
1820+
end: { line: 1, column: 7, index: 7 }
1821+
},
1822+
name: 'f'
1823+
},
1824+
init: {
1825+
type: 'ArrowFunctionExpression',
1826+
start: 10,
1827+
end: 36,
1828+
loc: {
1829+
start: { line: 1, column: 10, index: 10 },
1830+
end: { line: 1, column: 36, index: 36 }
1831+
},
1832+
id: null,
1833+
expression: false,
1834+
generator: false,
1835+
async: true,
1836+
params: [
1837+
{
1838+
type: 'RestElement',
1839+
start: 17,
1840+
end: 24,
1841+
loc: {
1842+
start: { line: 1, column: 17, index: 17 },
1843+
end: { line: 1, column: 24, index: 24 }
1844+
},
1845+
argument: {
1846+
type: 'Identifier',
1847+
start: 20,
1848+
end: 24,
1849+
loc: {
1850+
start: { line: 1, column: 20, index: 20 },
1851+
end: { line: 1, column: 24, index: 24 }
1852+
},
1853+
name: 'args'
1854+
},
1855+
typeAnnotation: {
1856+
type: 'TSTypeAnnotation',
1857+
start: 24,
1858+
end: 29,
1859+
loc: {
1860+
start: { line: 1, column: 24, index: 24 },
1861+
end: { line: 1, column: 29, index: 29 }
1862+
},
1863+
typeAnnotation: {
1864+
type: 'TSAnyKeyword',
1865+
start: 26,
1866+
end: 29,
1867+
loc: {
1868+
start: { line: 1, column: 26, index: 26 },
1869+
end: { line: 1, column: 29, index: 29 }
1870+
}
1871+
}
1872+
}
1873+
}
1874+
],
1875+
body: {
1876+
type: 'BlockStatement',
1877+
start: 34,
1878+
end: 36,
1879+
loc: {
1880+
start: { line: 1, column: 34, index: 34 },
1881+
end: { line: 1, column: 36, index: 36 }
1882+
},
1883+
body: []
1884+
}
1885+
}
1886+
}
1887+
],
1888+
kind: 'const'
1889+
}
1890+
],
1891+
sourceType: 'module'
16981892
}
16991893
};
17001894

__test__/arrow-function/type.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,16 @@ describe('arrow-function type test', () => {
6060

6161
equalNode(node, ArrowFunctionTypeSnapshot.GenericWithConst);
6262
});
63+
64+
it('rest parameter', () => {
65+
const node = parseSource(generateSource(['const f = (...args: any) => {}']));
66+
67+
equalNode(node, ArrowFunctionTypeSnapshot.RestParameter);
68+
});
69+
70+
it('async + rest parameter', () => {
71+
const node = parseSource(generateSource(['const f = async (...args: any) => {}']));
72+
73+
equalNode(node, ArrowFunctionTypeSnapshot.AsyncRestParameter);
74+
});
6375
});

src/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4503,6 +4503,9 @@ export function tsPlugin(options?: {
45034503
if (allowEmpty && this.type === tt.comma) elt = null;
45044504
else if (this.type === tt.ellipsis) {
45054505
elt = this.parseSpread(refDestructuringErrors);
4506+
if (this.maybeInArrowParameters && this.match(tt.colon)) {
4507+
elt.typeAnnotation = this.tsParseTypeAnnotation();
4508+
}
45064509
if (
45074510
refDestructuringErrors &&
45084511
this.type === tt.comma &&

0 commit comments

Comments
 (0)