mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' of github.com:Microsoft/TypeScript into usedbeforedeclaration-objectspread
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
// @strict: true
|
||||
// @lib: es6
|
||||
type Page = {close(): Promise<void>; content(): Promise<string>};
|
||||
type Browser = {close(): Promise<void>};
|
||||
declare function test1(): Promise<Browser>;
|
||||
declare function test2(obj: Browser): Promise<Page>;
|
||||
async function test(): Promise<string> {
|
||||
let browser: Browser | undefined = undefined;
|
||||
let page: Page | undefined = undefined;
|
||||
try {
|
||||
browser = await test1();
|
||||
page = await test2(browser);
|
||||
return await page.content();;
|
||||
} finally {
|
||||
if (page) {
|
||||
await page.close(); // ok
|
||||
}
|
||||
|
||||
if (browser) {
|
||||
await browser.close(); // ok
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare class Aborter { abort(): void };
|
||||
class Foo {
|
||||
abortController: Aborter | undefined = undefined;
|
||||
|
||||
async operation() {
|
||||
if (this.abortController !== undefined) {
|
||||
this.abortController.abort();
|
||||
this.abortController = undefined;
|
||||
}
|
||||
try {
|
||||
this.abortController = new Aborter();
|
||||
} catch (error) {
|
||||
if (this.abortController !== undefined) {
|
||||
this.abortController.abort(); // ok
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// @declaration: true
|
||||
export declare namespace A {
|
||||
namespace X { }
|
||||
}
|
||||
|
||||
class X { }
|
||||
|
||||
export class A {
|
||||
static X = X;
|
||||
}
|
||||
|
||||
export declare namespace Y {
|
||||
|
||||
}
|
||||
|
||||
export class Y { }
|
||||
@@ -121,3 +121,57 @@ const u: U = {} as any;
|
||||
u.a && u.b && f(u.a, u.b);
|
||||
|
||||
u.b && u.a && f(u.a, u.b);
|
||||
|
||||
// Repro from #29012
|
||||
|
||||
type Additive = '+' | '-';
|
||||
type Multiplicative = '*' | '/';
|
||||
|
||||
interface AdditiveObj {
|
||||
key: Additive
|
||||
}
|
||||
|
||||
interface MultiplicativeObj {
|
||||
key: Multiplicative
|
||||
}
|
||||
|
||||
type Obj = AdditiveObj | MultiplicativeObj
|
||||
|
||||
export function foo(obj: Obj) {
|
||||
switch (obj.key) {
|
||||
case '+': {
|
||||
onlyPlus(obj.key);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function onlyPlus(arg: '+') {
|
||||
return arg;
|
||||
}
|
||||
|
||||
// Repro from #29496
|
||||
|
||||
declare function never(value: never): never;
|
||||
|
||||
const enum BarEnum {
|
||||
bar1 = 1,
|
||||
bar2 = 2,
|
||||
}
|
||||
|
||||
type UnionOfBar = TypeBar1 | TypeBar2;
|
||||
type TypeBar1 = { type: BarEnum.bar1 };
|
||||
type TypeBar2 = { type: BarEnum.bar2 };
|
||||
|
||||
function func3(value: Partial<UnionOfBar>) {
|
||||
if (value.type !== undefined) {
|
||||
switch (value.type) {
|
||||
case BarEnum.bar1:
|
||||
break;
|
||||
case BarEnum.bar2:
|
||||
break;
|
||||
default:
|
||||
never(value.type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
// @skipLibCheck: true
|
||||
// @lib: es6
|
||||
const path = './foo';
|
||||
import(path,);
|
||||
@@ -0,0 +1,78 @@
|
||||
// @jsx: react
|
||||
// @strict: true
|
||||
// @filename: index.tsx
|
||||
/// <reference path="/.lib/react16.d.ts" />
|
||||
import * as React from "react";
|
||||
|
||||
interface Props {
|
||||
children: (x: number) => string;
|
||||
}
|
||||
|
||||
export function Blah(props: Props) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
// Incompatible child.
|
||||
var a = <Blah>
|
||||
{x => x}
|
||||
</Blah>
|
||||
|
||||
// Blah components don't accept text as child elements
|
||||
var a = <Blah>
|
||||
Hello unexpected text!
|
||||
</Blah>
|
||||
|
||||
// Blah components don't accept multiple children.
|
||||
var a = <Blah>
|
||||
{x => "" + x}
|
||||
{x => "" + x}
|
||||
</Blah>
|
||||
|
||||
interface PropsArr {
|
||||
children: ((x: number) => string)[];
|
||||
}
|
||||
|
||||
export function Blah2(props: PropsArr) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
// Incompatible child.
|
||||
var a = <Blah2>
|
||||
{x => x}
|
||||
</Blah2>
|
||||
|
||||
// Blah2 components don't accept text as child elements
|
||||
var a = <Blah2>
|
||||
Hello unexpected text!
|
||||
</Blah2>
|
||||
|
||||
// Blah2 components don't accept multiple children of the wrong type.
|
||||
var a = <Blah2>
|
||||
{x => x}
|
||||
{x => x}
|
||||
</Blah2>
|
||||
|
||||
type Cb = (x: number) => string;
|
||||
interface PropsMixed {
|
||||
children: Cb | Cb[];
|
||||
}
|
||||
|
||||
export function Blah3(props: PropsMixed) {
|
||||
return <></>;
|
||||
}
|
||||
|
||||
// Incompatible child.
|
||||
var a = <Blah3>
|
||||
{x => x}
|
||||
</Blah3>
|
||||
|
||||
// Blah3 components don't accept text as child elements
|
||||
var a = <Blah3>
|
||||
Hello unexpected text!
|
||||
</Blah3>
|
||||
|
||||
// Blah3 components don't accept multiple children of the wrong type.
|
||||
var a = <Blah3>
|
||||
{x => x}
|
||||
{x => x}
|
||||
</Blah3>
|
||||
@@ -0,0 +1,34 @@
|
||||
// @strict: true
|
||||
type ElementRef = (element: HTMLElement | null) => void;
|
||||
|
||||
type ThumbProps = {
|
||||
elementRef?: ElementRef;
|
||||
}
|
||||
|
||||
type ComponentProps = {
|
||||
thumbYProps?: ThumbProps;
|
||||
thumbXProps: ThumbProps;
|
||||
}
|
||||
|
||||
class Component {
|
||||
props!: ComponentProps;
|
||||
public thumbYElementRef = (ref: HTMLElement | null) => {
|
||||
typeof this.props.thumbYProps!.elementRef === 'function' && this.props.thumbYProps!.elementRef(ref);
|
||||
|
||||
typeof (this.props.thumbYProps!.elementRef) === 'function' && this.props.thumbYProps!.elementRef(ref);
|
||||
|
||||
typeof ((this.props).thumbYProps!.elementRef)! === 'function' && this.props.thumbYProps!.elementRef(ref);
|
||||
|
||||
typeof this.props.thumbXProps.elementRef === 'function' && this.props.thumbXProps.elementRef(ref);
|
||||
|
||||
typeof this.props.thumbXProps.elementRef === 'function' && (this.props).thumbXProps.elementRef(ref);
|
||||
|
||||
typeof this.props.thumbXProps.elementRef === 'function' && (this.props.thumbXProps).elementRef(ref);
|
||||
|
||||
typeof this.props.thumbXProps.elementRef === 'function' && ((this.props)!.thumbXProps)!.elementRef(ref);
|
||||
|
||||
typeof (this.props.thumbXProps).elementRef === 'function' && ((this.props)!.thumbXProps)!.elementRef(ref);
|
||||
|
||||
typeof this.props!.thumbXProps!.elementRef === 'function' && ((this.props)!.thumbXProps)!.elementRef(ref);
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
type Bar = ReturnType<<T>(x: T) => number>;
|
||||
declare const a: Bar;
|
||||
|
||||
function foo<T>(_x: T) {}
|
||||
const b = foo<<T>(x: T) => number>(() => 1);
|
||||
@@ -0,0 +1,26 @@
|
||||
// @strict: true
|
||||
type Obj = {} | undefined;
|
||||
|
||||
type User = {
|
||||
email: string;
|
||||
name: string;
|
||||
};
|
||||
|
||||
type PartialUser = Partial<User>;
|
||||
|
||||
// type PartialUser = {
|
||||
// email?: string;
|
||||
// name?: string;
|
||||
// };
|
||||
|
||||
function isUser(obj: Obj): obj is PartialUser {
|
||||
return true;
|
||||
}
|
||||
|
||||
function getUserName(obj: Obj) {
|
||||
if (isUser(obj)) {
|
||||
return obj.name;
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
@@ -1 +1,3 @@
|
||||
// @sourcemap: true
|
||||
|
||||
function a(...{a, b}) { }
|
||||
@@ -1 +1,3 @@
|
||||
// @sourcemap: true
|
||||
|
||||
function a(...[a, b]) { }
|
||||
@@ -0,0 +1,9 @@
|
||||
function a(...[a = 1, b = true]: string[]) { }
|
||||
|
||||
function b(...[...foo = []]: string[]) { }
|
||||
|
||||
function c(...{0: a, length, 3: d}: [boolean, string, number]) { }
|
||||
|
||||
function d(...[a, , , d]: [boolean, string, number]) { }
|
||||
|
||||
function e(...{0: a = 1, 1: b = true, ...rest: rest}: [boolean, string, number]) { }
|
||||
@@ -0,0 +1,6 @@
|
||||
declare function call<Fn extends (...args: any[]) => any>(
|
||||
fn: Fn,
|
||||
...args: Parameters<Fn>
|
||||
): any;
|
||||
|
||||
call(function* (a: 'a') { }); // error, 2nd argument required
|
||||
@@ -105,6 +105,21 @@ function CreateTypedArraysOf2() {
|
||||
return typedArrays;
|
||||
}
|
||||
|
||||
function CreateTypedArraysFromMapFn2<T>(obj:ArrayLike<T>, mapFn: (n:T, v:number)=> number) {
|
||||
var typedArrays = [];
|
||||
typedArrays[0] = Int8Array.from(obj, mapFn);
|
||||
typedArrays[1] = Uint8Array.from(obj, mapFn);
|
||||
typedArrays[2] = Int16Array.from(obj, mapFn);
|
||||
typedArrays[3] = Uint16Array.from(obj, mapFn);
|
||||
typedArrays[4] = Int32Array.from(obj, mapFn);
|
||||
typedArrays[5] = Uint32Array.from(obj, mapFn);
|
||||
typedArrays[6] = Float32Array.from(obj, mapFn);
|
||||
typedArrays[7] = Float64Array.from(obj, mapFn);
|
||||
typedArrays[8] = Uint8ClampedArray.from(obj, mapFn);
|
||||
|
||||
return typedArrays;
|
||||
}
|
||||
|
||||
function CreateTypedArraysFromMapFn(obj:ArrayLike<number>, mapFn: (n:number, v:number)=> number) {
|
||||
var typedArrays = [];
|
||||
typedArrays[0] = Int8Array.from(obj, mapFn);
|
||||
@@ -132,5 +147,20 @@ function CreateTypedArraysFromThisObj(obj:ArrayLike<number>, mapFn: (n:number, v
|
||||
typedArrays[7] = Float64Array.from(obj, mapFn, thisArg);
|
||||
typedArrays[8] = Uint8ClampedArray.from(obj, mapFn, thisArg);
|
||||
|
||||
return typedArrays;
|
||||
}
|
||||
|
||||
function CreateTypedArraysFromThisObj2<T>(obj:ArrayLike<T>, mapFn: (n:T, v:number)=> number, thisArg: {}) {
|
||||
var typedArrays = [];
|
||||
typedArrays[0] = Int8Array.from(obj, mapFn, thisArg);
|
||||
typedArrays[1] = Uint8Array.from(obj, mapFn, thisArg);
|
||||
typedArrays[2] = Int16Array.from(obj, mapFn, thisArg);
|
||||
typedArrays[3] = Uint16Array.from(obj, mapFn, thisArg);
|
||||
typedArrays[4] = Int32Array.from(obj, mapFn, thisArg);
|
||||
typedArrays[5] = Uint32Array.from(obj, mapFn, thisArg);
|
||||
typedArrays[6] = Float32Array.from(obj, mapFn, thisArg);
|
||||
typedArrays[7] = Float64Array.from(obj, mapFn, thisArg);
|
||||
typedArrays[8] = Uint8ClampedArray.from(obj, mapFn, thisArg);
|
||||
|
||||
return typedArrays;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// @strict: true
|
||||
// @module: esnext
|
||||
// @moduleResolution: node
|
||||
// @target: es2018
|
||||
// @filename: global.d.ts
|
||||
declare global {
|
||||
const React: typeof import("./module");
|
||||
}
|
||||
|
||||
export { };
|
||||
|
||||
// @filename: module.d.ts
|
||||
export = React;
|
||||
export as namespace React;
|
||||
|
||||
declare namespace React {
|
||||
function createRef(): any;
|
||||
}
|
||||
|
||||
// @filename: some_module.ts
|
||||
export { };
|
||||
React.createRef;
|
||||
|
||||
// @filename: emits.ts
|
||||
console.log("hello");
|
||||
React.createRef;
|
||||
@@ -106,3 +106,28 @@ class C6 extends Mix(Public, Public2) {
|
||||
C6.s
|
||||
}
|
||||
}
|
||||
|
||||
class ProtectedGeneric<T> {
|
||||
private privateMethod() {}
|
||||
protected protectedMethod() {}
|
||||
}
|
||||
|
||||
class ProtectedGeneric2<T> {
|
||||
private privateMethod() {}
|
||||
protected protectedMethod() {}
|
||||
}
|
||||
|
||||
function f7(x: ProtectedGeneric<{}> & ProtectedGeneric<{}>) {
|
||||
x.privateMethod(); // Error, private constituent makes method inaccessible
|
||||
x.protectedMethod(); // Error, protected when all constituents are protected
|
||||
}
|
||||
|
||||
function f8(x: ProtectedGeneric<{a: void;}> & ProtectedGeneric2<{a:void;b:void;}>) {
|
||||
x.privateMethod(); // Error, private constituent makes method inaccessible
|
||||
x.protectedMethod(); // Error, protected when all constituents are protected
|
||||
}
|
||||
|
||||
function f9(x: ProtectedGeneric<{a: void;}> & ProtectedGeneric<{a:void;b:void;}>) {
|
||||
x.privateMethod(); // Error, private constituent makes method inaccessible
|
||||
x.protectedMethod(); // Error, protected when all constituents are protected
|
||||
}
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
// @target: esnext
|
||||
// @module: commonjs
|
||||
// @noLib: true
|
||||
// @declaration: true
|
||||
// Test that passing noLib disables <reference lib> resolution.
|
||||
|
||||
// @filename: fakelib.ts
|
||||
interface Object { }
|
||||
interface Array<T> { }
|
||||
interface String { }
|
||||
interface Boolean { }
|
||||
interface Number { }
|
||||
interface Function { }
|
||||
interface RegExp { }
|
||||
interface IArguments { }
|
||||
|
||||
|
||||
// @filename: file1.ts
|
||||
/// <reference lib="dom" />
|
||||
export declare interface HTMLElement { field: string; }
|
||||
export const elem: HTMLElement = { field: 'a' };
|
||||
@@ -0,0 +1,23 @@
|
||||
// @target: esnext
|
||||
// @module: amd
|
||||
// @noLib: true
|
||||
// @declaration: true
|
||||
// @outFile: bundle.js
|
||||
|
||||
// Test that passing noLib disables <reference lib> resolution.
|
||||
|
||||
// @filename: fakelib.ts
|
||||
interface Object { }
|
||||
interface Array<T> { }
|
||||
interface String { }
|
||||
interface Boolean { }
|
||||
interface Number { }
|
||||
interface Function { }
|
||||
interface RegExp { }
|
||||
interface IArguments { }
|
||||
|
||||
|
||||
// @filename: file1.ts
|
||||
/// <reference lib="dom" />
|
||||
export declare interface HTMLElement { field: string; }
|
||||
export const elem: HTMLElement = { field: 'a' };
|
||||
+8
@@ -22,6 +22,14 @@ function foo<T>(t: T) {
|
||||
var rb3 = x in t;
|
||||
}
|
||||
|
||||
function unionCase<T, U>(t: T | U) {
|
||||
var rb4 = x in t;
|
||||
}
|
||||
|
||||
function unionCase2<T>(t: T | object) {
|
||||
var rb5 = x in t;
|
||||
}
|
||||
|
||||
interface X { x: number }
|
||||
interface Y { y: number }
|
||||
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
// @noEmit: true
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @Filename: paramTagNestedWithoutTopLevelObject.js
|
||||
|
||||
/**
|
||||
* @param {number} xyz.p
|
||||
*/
|
||||
function g(xyz) {
|
||||
return xyz.p;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// @noEmit: true
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @Filename: paramTagNestedWithoutTopLevelObject2.js
|
||||
|
||||
/**
|
||||
* @param {object} xyz.bar
|
||||
* @param {number} xyz.bar.p
|
||||
*/
|
||||
function g(xyz) {
|
||||
return xyz.bar.p;
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// @noEmit: true
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @Filename: paramTagNestedWithoutTopLevelObject3.js
|
||||
|
||||
/**
|
||||
* @param {object} xyz
|
||||
* @param {number} xyz.bar.p
|
||||
*/
|
||||
function g(xyz) {
|
||||
return xyz.bar.p;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// @noEmit: true
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @Filename: paramTagNestedWithoutTopLevelObject4.js
|
||||
|
||||
/**
|
||||
* @param {number} xyz.bar.p
|
||||
*/
|
||||
function g(xyz) {
|
||||
return xyz.bar.p;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// @filename: file.tsx
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @skipLibCheck: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react');
|
||||
|
||||
const Tag = (x: {}) => <div></div>;
|
||||
|
||||
// OK
|
||||
const k1 = <Tag />;
|
||||
const k2 = <Tag></Tag>;
|
||||
|
||||
// Not OK (excess children)
|
||||
const k3 = <Tag children={<div></div>} />;
|
||||
const k4 = <Tag key="1"><div></div></Tag>;
|
||||
const k5 = <Tag key="1"><div></div><div></div></Tag>;
|
||||
@@ -0,0 +1,23 @@
|
||||
// @noEmit: true
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @Filename: bug26885.js
|
||||
// @strict: true
|
||||
|
||||
function Multimap3() {
|
||||
this._map = {};
|
||||
};
|
||||
|
||||
Multimap3.prototype = {
|
||||
/**
|
||||
* @param {string} key
|
||||
* @returns {number} the value ok
|
||||
*/
|
||||
get(key) {
|
||||
return this._map[key + ''];
|
||||
}
|
||||
}
|
||||
|
||||
/** @type {Multimap3} */
|
||||
const map = new Multimap3();
|
||||
const n = map.get('hi')
|
||||
@@ -31,6 +31,10 @@ var varInitToConstDeclAmbient = constType;
|
||||
const constInitToConstCallWithTypeQuery: typeof constCall = constCall;
|
||||
const constInitToConstDeclAmbientWithTypeQuery: typeof constType = constType;
|
||||
|
||||
// assignment from any
|
||||
// https://github.com/Microsoft/TypeScript/issues/29108
|
||||
const fromAny: unique symbol = {} as any;
|
||||
|
||||
// function return inference
|
||||
function funcReturnConstCall() { return constCall; }
|
||||
function funcReturnLetCall() { return letCall; }
|
||||
|
||||
@@ -17,8 +17,8 @@ verify.codeFix({
|
||||
newFileContent:
|
||||
`import { I } from "./I";
|
||||
export class C implements I {
|
||||
x: import("/I").J;
|
||||
m(): import("/I").J {
|
||||
x: import("./I").J;
|
||||
m(): import("./I").J {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
}`,
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
verify.getAndApplyCodeFix(/*errorCode*/ undefined, 0);
|
||||
|
||||
verify.rangeIs(`
|
||||
m0(arg0: D): any {
|
||||
m0(arg0: import("./f2").D): any {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
`);
|
||||
@@ -0,0 +1,26 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: /dir/a.ts
|
||||
////declare const decorator: any;
|
||||
////class A {
|
||||
//// @decorator method() {};
|
||||
////};
|
||||
|
||||
// @Filename: /dir/tsconfig.json
|
||||
////{
|
||||
//// "compilerOptions": {
|
||||
//// }
|
||||
////}
|
||||
|
||||
goTo.file("/dir/a.ts");
|
||||
verify.codeFix({
|
||||
description: "Enable the 'experimentalDecorators' option in your configuration file",
|
||||
newFileContent: {
|
||||
"/dir/tsconfig.json":
|
||||
`{
|
||||
"compilerOptions": {
|
||||
"experimentalDecorators": true,
|
||||
}
|
||||
}`,
|
||||
},
|
||||
});
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: /dir/a.ts
|
||||
////declare const decorator: any;
|
||||
////class A {
|
||||
//// @decorator method() {};
|
||||
////};
|
||||
|
||||
// @Filename: /dir/tsconfig.json
|
||||
////{
|
||||
//// "compilerOptions": {
|
||||
//// "experimentalDecorators": false,
|
||||
//// }
|
||||
////}
|
||||
|
||||
goTo.file("/dir/a.ts");
|
||||
verify.codeFix({
|
||||
description: "Enable the 'experimentalDecorators' option in your configuration file",
|
||||
newFileContent: {
|
||||
"/dir/tsconfig.json":
|
||||
`{
|
||||
"compilerOptions": {
|
||||
"experimentalDecorators": true,
|
||||
}
|
||||
}`,
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: /dir/a.ts
|
||||
////declare const decorator: any;
|
||||
////class A {
|
||||
//// @decorator method() {};
|
||||
////};
|
||||
|
||||
// @Filename: /dir/tsconfig.json
|
||||
////{
|
||||
////}
|
||||
|
||||
goTo.file("/dir/a.ts");
|
||||
verify.codeFix({
|
||||
description: "Enable the 'experimentalDecorators' option in your configuration file",
|
||||
newFileContent: {
|
||||
"/dir/tsconfig.json":
|
||||
`{
|
||||
"compilerOptions": { "experimentalDecorators": true },
|
||||
}`,
|
||||
},
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: /dir/a.ts
|
||||
////declare const decorator: any;
|
||||
////class A {
|
||||
//// @decorator method() {};
|
||||
////};
|
||||
|
||||
goTo.file("/dir/a.ts");
|
||||
verify.not.codeFixAvailable();
|
||||
@@ -3,4 +3,4 @@
|
||||
////var a: Array<string> | Array<number>;
|
||||
////a./*1*/length
|
||||
|
||||
verify.quickInfoAt("1", "(property) length: number", "Gets or sets the length of the array. This is a number one higher than the highest element defined in an array.");
|
||||
verify.quickInfoAt("1", "(property) Array<T>.length: number", "Gets or sets the length of the array. This is a number one higher than the highest element defined in an array.");
|
||||
@@ -0,0 +1,5 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
////namespace wwer./**/w
|
||||
|
||||
verify.completions({ marker: "", exact: [], isNewIdentifierLocation: true });
|
||||
@@ -3,7 +3,7 @@
|
||||
////var y: Array<string>|Array<number>;
|
||||
////y.map/**/(
|
||||
|
||||
const text = "(property) map: (<U>(callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[]) | (<U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[])";
|
||||
const text = "(property) Array<T>.map: (<U>(callbackfn: (value: string, index: number, array: string[]) => U, thisArg?: any) => U[]) | (<U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[])";
|
||||
const documentation = "Calls a defined callback function on each element of an array, and returns an array that contains the results.";
|
||||
|
||||
verify.quickInfoAt("", text, documentation);
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
// Use `/src` to test that directory names are not included in conversion from module path to identifier.
|
||||
// @noLib: true
|
||||
|
||||
// @Filename: /src/foo-bar.ts
|
||||
////export = 0;
|
||||
|
||||
// @Filename: /src/b.ts
|
||||
////exp/*0*/
|
||||
////fooB/*1*/
|
||||
|
||||
goTo.marker("0");
|
||||
const preferences: FourSlashInterface.UserPreferences = { includeCompletionsForModuleExports: true };
|
||||
const exportEntry: FourSlashInterface.ExpectedCompletionEntryObject = { name: "fooBar", source: "/src/foo-bar", sourceDisplay: "./foo-bar", text: "(property) export=: 0", kind: "property", hasAction: true };
|
||||
verify.completions(
|
||||
{ marker: "0", exact: ["undefined", exportEntry, ...completion.statementKeywordsWithTypes], preferences },
|
||||
{ marker: "1", includes: exportEntry, preferences }
|
||||
);
|
||||
verify.applyCodeActionFromCompletion("0", {
|
||||
name: "fooBar",
|
||||
source: "/src/foo-bar",
|
||||
description: `Import 'fooBar' from module "./foo-bar"`,
|
||||
newFileContent: `import fooBar = require("./foo-bar");
|
||||
|
||||
exp
|
||||
fooB`,
|
||||
});
|
||||
@@ -0,0 +1,44 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: /node_modules/@types/three/three-core.d.ts
|
||||
////export class Vector3 {
|
||||
//// constructor(x?: number, y?: number, z?: number);
|
||||
//// x: number;
|
||||
//// y: number;
|
||||
////}
|
||||
|
||||
// @Filename: /node_modules/@types/three/index.d.ts
|
||||
////export * from "./three-core";
|
||||
////export as namespace [|{| "isWriteAccess": true, "isDefinition": true |}THREE|];
|
||||
|
||||
// @Filename: /typings/global.d.ts
|
||||
////import * as _THREE from '[|three|]';
|
||||
////declare global {
|
||||
//// const [|{| "isWriteAccess": true, "isDefinition": true |}THREE|]: typeof _THREE;
|
||||
////}
|
||||
|
||||
// @Filename: /src/index.ts
|
||||
////export const a = {};
|
||||
////let v = new [|THREE|].Vector2();
|
||||
|
||||
// @Filename: /tsconfig.json
|
||||
////{
|
||||
//// "compilerOptions": {
|
||||
//// "esModuleInterop": true,
|
||||
//// "outDir": "./build/js/",
|
||||
//// "noImplicitAny": true,
|
||||
//// "module": "es6",
|
||||
//// "target": "es6",
|
||||
//// "allowJs": true,
|
||||
//// "skipLibCheck": true,
|
||||
//// "lib": ["es2016", "dom"],
|
||||
//// "typeRoots": ["node_modules/@types/"],
|
||||
//// "types": ["three"]
|
||||
//// },
|
||||
//// "files": ["/src/index.ts", "typings/global.d.ts"]
|
||||
////}
|
||||
|
||||
// GH#29533
|
||||
// TODO:: this should be var THREE: typeof import instead of module name as var but thats existing issue and repros with quickInfo too.
|
||||
verify.singleReferenceGroup(`module "/node_modules/@types/three/index"
|
||||
var "/node_modules/@types/three/index": typeof import("/node_modules/@types/three/index")`);
|
||||
@@ -0,0 +1,56 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @Filename: /file1.ts
|
||||
////declare function log(s: string | number): void;
|
||||
////const [|{| "isWriteAccess": true, "isDefinition": true |}q|] = 1;
|
||||
////export { [|{| "isWriteAccess": true, "isDefinition": true |}q|] };
|
||||
////const x = {
|
||||
//// [|{| "isWriteAccess": true, "isDefinition": true |}z|]: 'value'
|
||||
////}
|
||||
////const { [|{| "isWriteAccess": true, "isDefinition": true |}z|] } = x;
|
||||
////log([|z|]);
|
||||
|
||||
// @Filename: /file2.ts
|
||||
////declare function log(s: string | number): void;
|
||||
////import { [|{| "isWriteAccess": true, "isDefinition": true |}q|] } from "./file1";
|
||||
////log([|q|] + 1);
|
||||
|
||||
verify.noErrors();
|
||||
|
||||
const [q0, q1, z0, z1, z2, q2, q3] = test.ranges();
|
||||
const qFile1Ranges = [q0, q1];
|
||||
const qFile2Ranges = [q2, q3];
|
||||
const qFile1ReferenceGroup: FourSlashInterface.ReferenceGroup = {
|
||||
definition: "const q: 1",
|
||||
ranges: qFile1Ranges
|
||||
};
|
||||
const qFile2ReferenceGroup: FourSlashInterface.ReferenceGroup = {
|
||||
definition: "(alias) const q: 1\nimport q",
|
||||
ranges: qFile2Ranges
|
||||
};
|
||||
verify.referenceGroups([q0, q1], [qFile1ReferenceGroup, qFile2ReferenceGroup]);
|
||||
verify.referenceGroups([q2, q3], [qFile2ReferenceGroup, qFile1ReferenceGroup]);
|
||||
|
||||
verify.renameLocations(q0, { ranges: [q0, { range: q1, suffixText: " as q" }], providePrefixAndSuffixTextForRename: true });
|
||||
verify.renameLocations(q1, { ranges: [{ range: q1, prefixText: "q as " }, q2, q3], providePrefixAndSuffixTextForRename: true });
|
||||
verify.renameLocations([q2, q3], { ranges: [{ range: q2, prefixText: "q as " }, q3], providePrefixAndSuffixTextForRename: true });
|
||||
|
||||
verify.renameLocations([q0, q1, q2, q3], { ranges: [q0, q1, q2, q3], providePrefixAndSuffixTextForRename: false });
|
||||
|
||||
const zReferenceGroup1: FourSlashInterface.ReferenceGroup = {
|
||||
definition: "(property) z: string",
|
||||
ranges: [z0]
|
||||
};
|
||||
const zReferenceGroup2: FourSlashInterface.ReferenceGroup = {
|
||||
definition: "const z: string",
|
||||
ranges: [z1, z2]
|
||||
};
|
||||
|
||||
verify.referenceGroups([z0], [{ ...zReferenceGroup1, ranges: [z0, z1] }]);
|
||||
verify.referenceGroups([z1], [zReferenceGroup1, zReferenceGroup2]);
|
||||
verify.referenceGroups([z2], [zReferenceGroup2]);
|
||||
|
||||
verify.renameLocations([z0], { ranges: [z0, { range: z1, suffixText: ": z" }], providePrefixAndSuffixTextForRename: true });
|
||||
verify.renameLocations([z1, z2], { ranges: [{ range: z1, prefixText: "z: " }, z2], providePrefixAndSuffixTextForRename: true });
|
||||
|
||||
verify.renameLocations([z0, z1, z2], { ranges: [z0, z1, z2], providePrefixAndSuffixTextForRename: false });
|
||||
@@ -27,4 +27,5 @@ verify.renameLocations(r2, [r0, r1, r2]);
|
||||
for (const range of [r3b, r4b]) {
|
||||
goTo.rangeStart(range);
|
||||
verify.renameInfoSucceeded(/*displayName*/ "/a.ts", /*fullDisplayName*/ "/a.ts", /*kind*/ "module", /*kindModifiers*/ "", /*fileToRename*/ "/a.ts", range);
|
||||
verify.renameInfoFailed("You cannot rename this element.", /*allowRenameOfImportPath*/ false);
|
||||
}
|
||||
|
||||
@@ -282,8 +282,8 @@ declare namespace FourSlashInterface {
|
||||
text: string;
|
||||
textSpan?: TextSpan;
|
||||
}[]): void;
|
||||
renameInfoSucceeded(displayName?: string, fullDisplayName?: string, kind?: string, kindModifiers?: string, fileToRename?: string, range?: Range): void;
|
||||
renameInfoFailed(message?: string): void;
|
||||
renameInfoSucceeded(displayName?: string, fullDisplayName?: string, kind?: string, kindModifiers?: string, fileToRename?: string, range?: Range, allowRenameOfImportPath?: boolean): void;
|
||||
renameInfoFailed(message?: string, allowRenameOfImportPath?: boolean): void;
|
||||
renameLocations(startRanges: ArrayOrSingle<Range>, options: RenameLocationsOptions): void;
|
||||
|
||||
/** Verify the quick info available at the current marker. */
|
||||
@@ -633,7 +633,8 @@ declare namespace FourSlashInterface {
|
||||
readonly findInStrings?: boolean;
|
||||
readonly findInComments?: boolean;
|
||||
readonly ranges: ReadonlyArray<RenameLocationOptions>;
|
||||
}
|
||||
readonly providePrefixAndSuffixTextForRename?: boolean;
|
||||
};
|
||||
type RenameLocationOptions = Range | { readonly range: Range, readonly prefixText?: string, readonly suffixText?: string };
|
||||
}
|
||||
declare function verifyOperationIsCancelled(f: any): void;
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
// Should go to object literals within cast expressions when invoked on interface
|
||||
|
||||
// @Filename: def.d.ts
|
||||
//// export interface Interface { P: number }
|
||||
|
||||
// @Filename: ref.ts
|
||||
//// import { Interface } from "./def";
|
||||
//// const c: I/*ref*/nterface = [|{ P: 2 }|];
|
||||
|
||||
verify.allRangesAppearInImplementationList("ref");
|
||||
@@ -0,0 +1,12 @@
|
||||
/// <reference path='fourslash.ts'/>
|
||||
|
||||
// Should go to object literals within cast expressions when invoked on interface
|
||||
|
||||
// @Filename: def.d.ts
|
||||
//// export type TypeAlias = { P: number }
|
||||
|
||||
// @Filename: ref.ts
|
||||
//// import { TypeAlias } from "./def";
|
||||
//// const c: T/*ref*/ypeAlias = [|{ P: 2 }|];
|
||||
|
||||
verify.allRangesAppearInImplementationList("ref");
|
||||
@@ -0,0 +1,21 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
// @Filename: file.tsx
|
||||
//// import React = require('react');
|
||||
//// [|<div/>;|]
|
||||
//// 1;
|
||||
|
||||
verify.moveToNewFile({
|
||||
newFileContents: {
|
||||
"/tests/cases/fourslash/file.tsx":
|
||||
`1;`,
|
||||
"/tests/cases/fourslash/newFile.tsx":
|
||||
`import React = require('react');
|
||||
<div />;
|
||||
`,
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
// @Filename: file.tsx
|
||||
//// import React = require('react');
|
||||
//// [|<div/>;|]
|
||||
//// <div/>;
|
||||
|
||||
verify.moveToNewFile({
|
||||
newFileContents: {
|
||||
"/tests/cases/fourslash/file.tsx":
|
||||
`import React = require('react');
|
||||
<div/>;`,
|
||||
"/tests/cases/fourslash/newFile.tsx":
|
||||
`import React = require('react');
|
||||
<div />;
|
||||
`,
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,21 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
// @Filename: file.tsx
|
||||
//// import React = require('react');
|
||||
//// [|1;|]
|
||||
//// <div/>;
|
||||
|
||||
verify.moveToNewFile({
|
||||
newFileContents: {
|
||||
"/tests/cases/fourslash/file.tsx":
|
||||
`import React = require('react');
|
||||
<div/>;`,
|
||||
"/tests/cases/fourslash/newFile.tsx":
|
||||
`1;
|
||||
`,
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @jsx: preserve
|
||||
// @noLib: true
|
||||
// @libFiles: react.d.ts,lib.d.ts,leftpad.d.ts
|
||||
|
||||
// @Filename: file.tsx
|
||||
//// import React = require('leftpad');
|
||||
//// [|function F() {
|
||||
//// const React = import("react");
|
||||
//// <div/>;
|
||||
//// }|]
|
||||
//// React;
|
||||
|
||||
verify.moveToNewFile({
|
||||
newFileContents: {
|
||||
"/tests/cases/fourslash/file.tsx":
|
||||
`import React = require('leftpad');
|
||||
React;`,
|
||||
// NB: A perfect implementation would not copy over the import
|
||||
"/tests/cases/fourslash/F.tsx":
|
||||
`import React = require('leftpad');
|
||||
function F() {
|
||||
const React = import("react");
|
||||
<div />;
|
||||
}
|
||||
`,
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
/// <reference path="fourslash.ts" />
|
||||
|
||||
// @Filename: class.ts
|
||||
////export class Class { }
|
||||
// @Filename: interface.ts
|
||||
////import { Class } from './class';
|
||||
////
|
||||
////export interface Foo {
|
||||
//// x: Class;
|
||||
////}
|
||||
// @Filename: index.ts
|
||||
////import { Foo } from './interface';
|
||||
////
|
||||
////class /*1*/X implements Foo {}
|
||||
goTo.marker("1");
|
||||
verify.codeFix({
|
||||
index: 0,
|
||||
description: "Implement interface 'Foo'",
|
||||
newFileContent: {
|
||||
"/tests/cases/fourslash/index.ts": `import { Foo } from './interface';
|
||||
|
||||
class X implements Foo {
|
||||
x: import("./class").Class;
|
||||
}`
|
||||
}
|
||||
});
|
||||
@@ -27,6 +27,7 @@ goTo.eachRange(range => {
|
||||
const name = target === "dir" ? "/dir" : target === "dir/index" ? "/dir/index.ts" : "/a.ts";
|
||||
const kind = target === "dir" ? "directory" : "module";
|
||||
verify.renameInfoSucceeded(/*displayName*/ name, /*fullDisplayName*/ name, /*kind*/ kind, /*kindModifiers*/ "", /*fileToRename*/ name, range);
|
||||
verify.renameInfoFailed("You cannot rename this element.", /*allowRenameOfImportPath*/ false);
|
||||
});
|
||||
|
||||
goTo.marker("global");
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/// <reference path="../fourslash.ts" />
|
||||
|
||||
////interface I<[|T|]> extends I<[|T|]>, [|T|] {
|
||||
////}
|
||||
|
||||
verify.rangesAreDocumentHighlights();
|
||||
@@ -0,0 +1,6 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////console.log()
|
||||
/////**/
|
||||
|
||||
verify.noSignatureHelpForTriggerReason({ kind: "invoked" }, "");
|
||||
Reference in New Issue
Block a user