mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-12 12:57:11 -06:00
Parse generic function types in import type argument lists (#31079)
* Parenthesize in import type node factory * And now parse unparenthesized generic functions so we can handle parsing the older output
This commit is contained in:
parent
8fc6640f55
commit
d7f03fb0fa
@ -845,7 +845,7 @@ namespace ts {
|
||||
const node = <ImportTypeNode>createSynthesizedNode(SyntaxKind.ImportType);
|
||||
node.argument = argument;
|
||||
node.qualifier = qualifier;
|
||||
node.typeArguments = asNodeArray(typeArguments);
|
||||
node.typeArguments = parenthesizeTypeParameters(typeArguments);
|
||||
node.isTypeOf = isTypeOf;
|
||||
return node;
|
||||
}
|
||||
|
||||
@ -2922,7 +2922,9 @@ namespace ts {
|
||||
if (parseOptional(SyntaxKind.DotToken)) {
|
||||
node.qualifier = parseEntityName(/*allowReservedWords*/ true, Diagnostics.Type_expected);
|
||||
}
|
||||
node.typeArguments = tryParseTypeArguments();
|
||||
if (!scanner.hasPrecedingLineBreak() && reScanLessThanToken() === SyntaxKind.LessThanToken) {
|
||||
node.typeArguments = parseBracketedList(ParsingContext.TypeArguments, parseType, SyntaxKind.LessThanToken, SyntaxKind.GreaterThanToken);
|
||||
}
|
||||
return finishNode(node);
|
||||
}
|
||||
|
||||
|
||||
@ -0,0 +1,41 @@
|
||||
//// [tests/cases/compiler/importTypeGenericArrowTypeParenthesized.ts] ////
|
||||
|
||||
//// [module.d.ts]
|
||||
declare module "module" {
|
||||
export interface Modifier<T> { }
|
||||
|
||||
export function fn<T>(x: T): Modifier<T>;
|
||||
}
|
||||
//// [index.ts]
|
||||
import { fn } from "module";
|
||||
|
||||
export const fail1 = fn(<T>(x: T): T => x);
|
||||
export const fail2 = fn(function<T>(x: T): T {
|
||||
return x;
|
||||
});
|
||||
|
||||
export const works1 = fn((x: number) => x);
|
||||
type MakeItWork = <T>(x: T) => T;
|
||||
export const works2 = fn<MakeItWork>(x => x);
|
||||
|
||||
|
||||
//// [index.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
var module_1 = require("module");
|
||||
exports.fail1 = module_1.fn(function (x) { return x; });
|
||||
exports.fail2 = module_1.fn(function (x) {
|
||||
return x;
|
||||
});
|
||||
exports.works1 = module_1.fn(function (x) { return x; });
|
||||
exports.works2 = module_1.fn(function (x) { return x; });
|
||||
|
||||
|
||||
//// [index.d.ts]
|
||||
/// <reference path="module.d.ts" />
|
||||
export declare const fail1: import("module").Modifier<(<T>(x: T) => T)>;
|
||||
export declare const fail2: import("module").Modifier<(<T>(x: T) => T)>;
|
||||
export declare const works1: import("module").Modifier<(x: number) => number>;
|
||||
declare type MakeItWork = <T>(x: T) => T;
|
||||
export declare const works2: import("module").Modifier<MakeItWork>;
|
||||
export {};
|
||||
@ -0,0 +1,62 @@
|
||||
=== tests/cases/compiler/module.d.ts ===
|
||||
declare module "module" {
|
||||
>"module" : Symbol("module", Decl(module.d.ts, 0, 0))
|
||||
|
||||
export interface Modifier<T> { }
|
||||
>Modifier : Symbol(Modifier, Decl(module.d.ts, 0, 25))
|
||||
>T : Symbol(T, Decl(module.d.ts, 1, 30))
|
||||
|
||||
export function fn<T>(x: T): Modifier<T>;
|
||||
>fn : Symbol(fn, Decl(module.d.ts, 1, 36))
|
||||
>T : Symbol(T, Decl(module.d.ts, 3, 23))
|
||||
>x : Symbol(x, Decl(module.d.ts, 3, 26))
|
||||
>T : Symbol(T, Decl(module.d.ts, 3, 23))
|
||||
>Modifier : Symbol(Modifier, Decl(module.d.ts, 0, 25))
|
||||
>T : Symbol(T, Decl(module.d.ts, 3, 23))
|
||||
}
|
||||
=== tests/cases/compiler/index.ts ===
|
||||
import { fn } from "module";
|
||||
>fn : Symbol(fn, Decl(index.ts, 0, 8))
|
||||
|
||||
export const fail1 = fn(<T>(x: T): T => x);
|
||||
>fail1 : Symbol(fail1, Decl(index.ts, 2, 12))
|
||||
>fn : Symbol(fn, Decl(index.ts, 0, 8))
|
||||
>T : Symbol(T, Decl(index.ts, 2, 25))
|
||||
>x : Symbol(x, Decl(index.ts, 2, 28))
|
||||
>T : Symbol(T, Decl(index.ts, 2, 25))
|
||||
>T : Symbol(T, Decl(index.ts, 2, 25))
|
||||
>x : Symbol(x, Decl(index.ts, 2, 28))
|
||||
|
||||
export const fail2 = fn(function<T>(x: T): T {
|
||||
>fail2 : Symbol(fail2, Decl(index.ts, 3, 12))
|
||||
>fn : Symbol(fn, Decl(index.ts, 0, 8))
|
||||
>T : Symbol(T, Decl(index.ts, 3, 33))
|
||||
>x : Symbol(x, Decl(index.ts, 3, 36))
|
||||
>T : Symbol(T, Decl(index.ts, 3, 33))
|
||||
>T : Symbol(T, Decl(index.ts, 3, 33))
|
||||
|
||||
return x;
|
||||
>x : Symbol(x, Decl(index.ts, 3, 36))
|
||||
|
||||
});
|
||||
|
||||
export const works1 = fn((x: number) => x);
|
||||
>works1 : Symbol(works1, Decl(index.ts, 7, 12))
|
||||
>fn : Symbol(fn, Decl(index.ts, 0, 8))
|
||||
>x : Symbol(x, Decl(index.ts, 7, 26))
|
||||
>x : Symbol(x, Decl(index.ts, 7, 26))
|
||||
|
||||
type MakeItWork = <T>(x: T) => T;
|
||||
>MakeItWork : Symbol(MakeItWork, Decl(index.ts, 7, 43))
|
||||
>T : Symbol(T, Decl(index.ts, 8, 19))
|
||||
>x : Symbol(x, Decl(index.ts, 8, 22))
|
||||
>T : Symbol(T, Decl(index.ts, 8, 19))
|
||||
>T : Symbol(T, Decl(index.ts, 8, 19))
|
||||
|
||||
export const works2 = fn<MakeItWork>(x => x);
|
||||
>works2 : Symbol(works2, Decl(index.ts, 9, 12))
|
||||
>fn : Symbol(fn, Decl(index.ts, 0, 8))
|
||||
>MakeItWork : Symbol(MakeItWork, Decl(index.ts, 7, 43))
|
||||
>x : Symbol(x, Decl(index.ts, 9, 37))
|
||||
>x : Symbol(x, Decl(index.ts, 9, 37))
|
||||
|
||||
@ -0,0 +1,54 @@
|
||||
=== tests/cases/compiler/module.d.ts ===
|
||||
declare module "module" {
|
||||
>"module" : typeof import("module")
|
||||
|
||||
export interface Modifier<T> { }
|
||||
|
||||
export function fn<T>(x: T): Modifier<T>;
|
||||
>fn : <T>(x: T) => Modifier<T>
|
||||
>x : T
|
||||
}
|
||||
=== tests/cases/compiler/index.ts ===
|
||||
import { fn } from "module";
|
||||
>fn : <T>(x: T) => import("module").Modifier<T>
|
||||
|
||||
export const fail1 = fn(<T>(x: T): T => x);
|
||||
>fail1 : import("module").Modifier<(<T>(x: T) => T)>
|
||||
>fn(<T>(x: T): T => x) : import("module").Modifier<(<T>(x: T) => T)>
|
||||
>fn : <T>(x: T) => import("module").Modifier<T>
|
||||
><T>(x: T): T => x : <T>(x: T) => T
|
||||
>x : T
|
||||
>x : T
|
||||
|
||||
export const fail2 = fn(function<T>(x: T): T {
|
||||
>fail2 : import("module").Modifier<(<T>(x: T) => T)>
|
||||
>fn(function<T>(x: T): T { return x;}) : import("module").Modifier<(<T>(x: T) => T)>
|
||||
>fn : <T>(x: T) => import("module").Modifier<T>
|
||||
>function<T>(x: T): T { return x;} : <T>(x: T) => T
|
||||
>x : T
|
||||
|
||||
return x;
|
||||
>x : T
|
||||
|
||||
});
|
||||
|
||||
export const works1 = fn((x: number) => x);
|
||||
>works1 : import("module").Modifier<(x: number) => number>
|
||||
>fn((x: number) => x) : import("module").Modifier<(x: number) => number>
|
||||
>fn : <T>(x: T) => import("module").Modifier<T>
|
||||
>(x: number) => x : (x: number) => number
|
||||
>x : number
|
||||
>x : number
|
||||
|
||||
type MakeItWork = <T>(x: T) => T;
|
||||
>MakeItWork : MakeItWork
|
||||
>x : T
|
||||
|
||||
export const works2 = fn<MakeItWork>(x => x);
|
||||
>works2 : import("module").Modifier<MakeItWork>
|
||||
>fn<MakeItWork>(x => x) : import("module").Modifier<MakeItWork>
|
||||
>fn : <T>(x: T) => import("module").Modifier<T>
|
||||
>x => x : <T>(x: T) => T
|
||||
>x : T
|
||||
>x : T
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
tests/cases/compiler/importTypeWithUnparenthesizedGenericFunctionParsed.ts(1,36): error TS2307: Cannot find module 'module'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/importTypeWithUnparenthesizedGenericFunctionParsed.ts (1 errors) ====
|
||||
export declare const fail1: import("module").Modifier<<T>(x: T) => T>; // shouldn't be a parse error
|
||||
~~~~~~~~
|
||||
!!! error TS2307: Cannot find module 'module'.
|
||||
@ -0,0 +1,6 @@
|
||||
//// [importTypeWithUnparenthesizedGenericFunctionParsed.ts]
|
||||
export declare const fail1: import("module").Modifier<<T>(x: T) => T>; // shouldn't be a parse error
|
||||
|
||||
//// [importTypeWithUnparenthesizedGenericFunctionParsed.js]
|
||||
"use strict";
|
||||
exports.__esModule = true;
|
||||
@ -0,0 +1,8 @@
|
||||
=== tests/cases/compiler/importTypeWithUnparenthesizedGenericFunctionParsed.ts ===
|
||||
export declare const fail1: import("module").Modifier<<T>(x: T) => T>; // shouldn't be a parse error
|
||||
>fail1 : Symbol(fail1, Decl(importTypeWithUnparenthesizedGenericFunctionParsed.ts, 0, 20))
|
||||
>T : Symbol(T, Decl(importTypeWithUnparenthesizedGenericFunctionParsed.ts, 0, 55))
|
||||
>x : Symbol(x, Decl(importTypeWithUnparenthesizedGenericFunctionParsed.ts, 0, 58))
|
||||
>T : Symbol(T, Decl(importTypeWithUnparenthesizedGenericFunctionParsed.ts, 0, 55))
|
||||
>T : Symbol(T, Decl(importTypeWithUnparenthesizedGenericFunctionParsed.ts, 0, 55))
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
=== tests/cases/compiler/importTypeWithUnparenthesizedGenericFunctionParsed.ts ===
|
||||
export declare const fail1: import("module").Modifier<<T>(x: T) => T>; // shouldn't be a parse error
|
||||
>fail1 : any
|
||||
>x : T
|
||||
|
||||
@ -0,0 +1,18 @@
|
||||
// @declaration: true
|
||||
// @filename: module.d.ts
|
||||
declare module "module" {
|
||||
export interface Modifier<T> { }
|
||||
|
||||
export function fn<T>(x: T): Modifier<T>;
|
||||
}
|
||||
// @filename: index.ts
|
||||
import { fn } from "module";
|
||||
|
||||
export const fail1 = fn(<T>(x: T): T => x);
|
||||
export const fail2 = fn(function<T>(x: T): T {
|
||||
return x;
|
||||
});
|
||||
|
||||
export const works1 = fn((x: number) => x);
|
||||
type MakeItWork = <T>(x: T) => T;
|
||||
export const works2 = fn<MakeItWork>(x => x);
|
||||
@ -0,0 +1 @@
|
||||
export declare const fail1: import("module").Modifier<<T>(x: T) => T>; // shouldn't be a parse error
|
||||
Loading…
x
Reference in New Issue
Block a user