Merge pull request #6855 from Microsoft/destructuringInTypes

Destructuring parameters in function/constructor types
This commit is contained in:
Anders Hejlsberg
2016-02-03 09:05:24 -08:00
5 changed files with 268 additions and 11 deletions
+27 -11
View File
@@ -2450,10 +2450,27 @@ namespace ts {
if (token === SyntaxKind.LessThanToken) {
return true;
}
return token === SyntaxKind.OpenParenToken && lookAhead(isUnambiguouslyStartOfFunctionType);
}
function skipParameterStart(): boolean {
if (isModifierKind(token)) {
// Skip modifiers
parseModifiers();
}
if (isIdentifier()) {
nextToken();
return true;
}
if (token === SyntaxKind.OpenBracketToken || token === SyntaxKind.OpenBraceToken) {
// Return true if we can parse an array or object binding pattern with no errors
const previousErrorCount = parseDiagnostics.length;
parseIdentifierOrPattern();
return previousErrorCount === parseDiagnostics.length;
}
return false;
}
function isUnambiguouslyStartOfFunctionType() {
nextToken();
if (token === SyntaxKind.CloseParenToken || token === SyntaxKind.DotDotDotToken) {
@@ -2461,22 +2478,21 @@ namespace ts {
// ( ...
return true;
}
if (isIdentifier() || isModifierKind(token)) {
nextToken();
if (skipParameterStart()) {
// We successfully skipped modifiers (if any) and an identifier or binding pattern,
// now see if we have something that indicates a parameter declaration
if (token === SyntaxKind.ColonToken || token === SyntaxKind.CommaToken ||
token === SyntaxKind.QuestionToken || token === SyntaxKind.EqualsToken ||
isIdentifier() || isModifierKind(token)) {
// ( id :
// ( id ,
// ( id ?
// ( id =
// ( modifier id
token === SyntaxKind.QuestionToken || token === SyntaxKind.EqualsToken) {
// ( xxx :
// ( xxx ,
// ( xxx ?
// ( xxx =
return true;
}
if (token === SyntaxKind.CloseParenToken) {
nextToken();
if (token === SyntaxKind.EqualsGreaterThanToken) {
// ( id ) =>
// ( xxx ) =>
return true;
}
}
@@ -0,0 +1,61 @@
//// [destructuringInFunctionType.ts]
interface a { a }
interface b { b }
interface c { c }
type T1 = ([a, b, c]);
type F1 = ([a, b, c]) => void;
type T2 = ({ a });
type F2 = ({ a }) => void;
type T3 = ([{ a: b }, { b: a }]);
type F3 = ([{ a: b }, { b: a }]) => void;
type T4 = ([{ a: [b, c] }]);
type F4 = ([{ a: [b, c] }]) => void;
type C1 = new ([{ a: [b, c] }]) => void;
var v1 = ([a, b, c]) => "hello";
var v2: ([a, b, c]) => string;
//// [destructuringInFunctionType.js]
var v1 = function (_a) {
var a = _a[0], b = _a[1], c = _a[2];
return "hello";
};
var v2;
//// [destructuringInFunctionType.d.ts]
interface a {
a: any;
}
interface b {
b: any;
}
interface c {
c: any;
}
declare type T1 = ([a, b, c]);
declare type F1 = ([a, b, c]) => void;
declare type T2 = ({
a;
});
declare type F2 = ({a}) => void;
declare type T3 = ([{
a: b;
}, {
b: a;
}]);
declare type F3 = ([{a: b}, {b: a}]) => void;
declare type T4 = ([{
a: [b, c];
}]);
declare type F4 = ([{a: [b, c]}]) => void;
declare type C1 = new ([{a: [b, c]}]) => void;
declare var v1: ([a, b, c]: [any, any, any]) => string;
declare var v2: ([a, b, c]) => string;
@@ -0,0 +1,78 @@
=== tests/cases/conformance/es6/destructuring/destructuringInFunctionType.ts ===
interface a { a }
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 0, 0))
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 1, 13))
interface b { b }
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 1, 17))
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 2, 13))
interface c { c }
>c : Symbol(c, Decl(destructuringInFunctionType.ts, 2, 17))
>c : Symbol(c, Decl(destructuringInFunctionType.ts, 3, 13))
type T1 = ([a, b, c]);
>T1 : Symbol(T1, Decl(destructuringInFunctionType.ts, 3, 17))
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 0, 0))
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 1, 17))
>c : Symbol(c, Decl(destructuringInFunctionType.ts, 2, 17))
type F1 = ([a, b, c]) => void;
>F1 : Symbol(F1, Decl(destructuringInFunctionType.ts, 5, 22))
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 6, 12))
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 6, 14))
>c : Symbol(c, Decl(destructuringInFunctionType.ts, 6, 17))
type T2 = ({ a });
>T2 : Symbol(T2, Decl(destructuringInFunctionType.ts, 6, 30))
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 8, 12))
type F2 = ({ a }) => void;
>F2 : Symbol(F2, Decl(destructuringInFunctionType.ts, 8, 18))
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 9, 12))
type T3 = ([{ a: b }, { b: a }]);
>T3 : Symbol(T3, Decl(destructuringInFunctionType.ts, 9, 26))
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 11, 13))
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 1, 17))
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 11, 23))
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 0, 0))
type F3 = ([{ a: b }, { b: a }]) => void;
>F3 : Symbol(F3, Decl(destructuringInFunctionType.ts, 11, 33))
>a : Symbol(a)
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 12, 13))
>b : Symbol(b)
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 12, 23))
type T4 = ([{ a: [b, c] }]);
>T4 : Symbol(T4, Decl(destructuringInFunctionType.ts, 12, 41))
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 14, 13))
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 1, 17))
>c : Symbol(c, Decl(destructuringInFunctionType.ts, 2, 17))
type F4 = ([{ a: [b, c] }]) => void;
>F4 : Symbol(F4, Decl(destructuringInFunctionType.ts, 14, 28))
>a : Symbol(a)
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 15, 18))
>c : Symbol(c, Decl(destructuringInFunctionType.ts, 15, 20))
type C1 = new ([{ a: [b, c] }]) => void;
>C1 : Symbol(C1, Decl(destructuringInFunctionType.ts, 15, 36))
>a : Symbol(a)
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 17, 22))
>c : Symbol(c, Decl(destructuringInFunctionType.ts, 17, 24))
var v1 = ([a, b, c]) => "hello";
>v1 : Symbol(v1, Decl(destructuringInFunctionType.ts, 19, 3))
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 19, 11))
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 19, 13))
>c : Symbol(c, Decl(destructuringInFunctionType.ts, 19, 16))
var v2: ([a, b, c]) => string;
>v2 : Symbol(v2, Decl(destructuringInFunctionType.ts, 20, 3))
>a : Symbol(a, Decl(destructuringInFunctionType.ts, 20, 10))
>b : Symbol(b, Decl(destructuringInFunctionType.ts, 20, 12))
>c : Symbol(c, Decl(destructuringInFunctionType.ts, 20, 15))
@@ -0,0 +1,80 @@
=== tests/cases/conformance/es6/destructuring/destructuringInFunctionType.ts ===
interface a { a }
>a : a
>a : any
interface b { b }
>b : b
>b : any
interface c { c }
>c : c
>c : any
type T1 = ([a, b, c]);
>T1 : [a, b, c]
>a : a
>b : b
>c : c
type F1 = ([a, b, c]) => void;
>F1 : ([a, b, c]: [any, any, any]) => void
>a : any
>b : any
>c : any
type T2 = ({ a });
>T2 : { a: any; }
>a : any
type F2 = ({ a }) => void;
>F2 : ({ a }: { a: any; }) => void
>a : any
type T3 = ([{ a: b }, { b: a }]);
>T3 : [{ a: b; }, { b: a; }]
>a : b
>b : b
>b : a
>a : a
type F3 = ([{ a: b }, { b: a }]) => void;
>F3 : ([{ a: b }, { b: a }]: [{ a: any; }, { b: any; }]) => void
>a : any
>b : any
>b : any
>a : any
type T4 = ([{ a: [b, c] }]);
>T4 : [{ a: [b, c]; }]
>a : [b, c]
>b : b
>c : c
type F4 = ([{ a: [b, c] }]) => void;
>F4 : ([{ a: [b, c] }]: [{ a: [any, any]; }]) => void
>a : any
>b : any
>c : any
type C1 = new ([{ a: [b, c] }]) => void;
>C1 : new ([{ a: [b, c] }]: [{ a: [any, any]; }]) => void
>a : any
>b : any
>c : any
var v1 = ([a, b, c]) => "hello";
>v1 : ([a, b, c]: [any, any, any]) => string
>([a, b, c]) => "hello" : ([a, b, c]: [any, any, any]) => string
>a : any
>b : any
>c : any
>"hello" : string
var v2: ([a, b, c]) => string;
>v2 : ([a, b, c]: [any, any, any]) => string
>a : any
>b : any
>c : any
@@ -0,0 +1,22 @@
// @declaration: true
interface a { a }
interface b { b }
interface c { c }
type T1 = ([a, b, c]);
type F1 = ([a, b, c]) => void;
type T2 = ({ a });
type F2 = ({ a }) => void;
type T3 = ([{ a: b }, { b: a }]);
type F3 = ([{ a: b }, { b: a }]) => void;
type T4 = ([{ a: [b, c] }]);
type F4 = ([{ a: [b, c] }]) => void;
type C1 = new ([{ a: [b, c] }]) => void;
var v1 = ([a, b, c]) => "hello";
var v2: ([a, b, c]) => string;