mirror of
https://github.com/microsoft/TypeScript.git
synced 2025-11-18 17:21:48 +00:00
Merge branch 'master' into fix2-getConstraintOfIndexedAccess
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
import Namespace from "./b";
|
||||
export var x = new Namespace.Foo();
|
||||
|
||||
// @Filename: b.ts
|
||||
// @Filename: b.d.ts
|
||||
export class Foo {
|
||||
member: string;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
import Namespace from "./b";
|
||||
export var x = new Namespace.Foo();
|
||||
|
||||
// @Filename: b.ts
|
||||
// @Filename: b.d.ts
|
||||
export class Foo {
|
||||
member: string;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
// @noImplicitAny: true
|
||||
|
||||
type Foo = {[P in "bar"]};
|
||||
@@ -0,0 +1,5 @@
|
||||
// TODO: remove lib hack when https://github.com/Microsoft/TypeScript/issues/20454 is fixed
|
||||
type Fn<T extends object> = <U extends T>(subj: U) => U
|
||||
function doStuff<T extends object, T1 extends T>(a: Array<Fn<T>>, b: Array<Fn<T1>>) {
|
||||
b.concat(a);
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
// @lib: es2015
|
||||
|
||||
// Tests fix for #20432, ensures Array.from accepts all valid inputs
|
||||
// Also tests for #19682
|
||||
|
||||
interface A {
|
||||
a: string;
|
||||
}
|
||||
|
||||
interface B {
|
||||
b: string;
|
||||
}
|
||||
|
||||
const inputA: A[] = [];
|
||||
const inputB: B[] = [];
|
||||
const inputALike: ArrayLike<A> = { length: 0 };
|
||||
const inputARand = getEither(inputA, inputALike);
|
||||
|
||||
const result1: A[] = Array.from(inputA);
|
||||
const result2: A[] = Array.from(inputA.values());
|
||||
const result3: B[] = Array.from(inputA.values()); // expect error
|
||||
const result4: A[] = Array.from(inputB, ({ b }): A => ({ a: b }));
|
||||
const result5: A[] = Array.from(inputALike);
|
||||
const result6: B[] = Array.from(inputALike); // expect error
|
||||
const result7: B[] = Array.from(inputALike, ({ a }): B => ({ b: a }));
|
||||
const result8: A[] = Array.from(inputARand);
|
||||
const result9: B[] = Array.from(inputARand, ({ a }): B => ({ b: a }));
|
||||
|
||||
// if this is written inline, the compiler seems to infer
|
||||
// the ?: as always taking the false branch, narrowing to ArrayLike<T>,
|
||||
// even when the type is written as : Iterable<T>|ArrayLike<T>
|
||||
function getEither<T> (in1: Iterable<T>, in2: ArrayLike<T>) {
|
||||
return Math.random() > 0.5 ? in1 : in2;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
class Base {
|
||||
n: Base | string;
|
||||
fn() {
|
||||
return 10;
|
||||
}
|
||||
}
|
||||
class Derived extends Base {
|
||||
n: Derived | string;
|
||||
fn() {
|
||||
return 10 as number | string;
|
||||
}
|
||||
}
|
||||
class DerivedInterface implements Base {
|
||||
n: DerivedInterface | string;
|
||||
fn() {
|
||||
return 10 as number | string;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// https://github.com/Microsoft/TypeScript/issues/16861
|
||||
class BaseType<T> {
|
||||
bar: T
|
||||
}
|
||||
|
||||
class NextType<C extends { someProp: any }, T = C['someProp']> extends BaseType<T> {
|
||||
baz: string;
|
||||
}
|
||||
|
||||
class Foo extends NextType<Foo> {
|
||||
someProp: {
|
||||
test: true
|
||||
}
|
||||
}
|
||||
|
||||
const foo = new Foo();
|
||||
foo.bar.test
|
||||
@@ -0,0 +1,8 @@
|
||||
class A {}
|
||||
if (true) {
|
||||
class B extends A {}
|
||||
|
||||
const foo = function () {
|
||||
new B();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
class A {
|
||||
private x: number;
|
||||
}
|
||||
|
||||
class B implements A {}
|
||||
@@ -0,0 +1,18 @@
|
||||
|
||||
class Foo {
|
||||
static enumMember = Enum.A;
|
||||
static objLiteralMember = ObjLiteral.A;
|
||||
static namespaceMember = Namespace.A;
|
||||
}
|
||||
|
||||
enum Enum {
|
||||
A
|
||||
}
|
||||
|
||||
const ObjLiteral = {
|
||||
A: 0
|
||||
};
|
||||
|
||||
namespace Namespace {
|
||||
export let A = 0
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
interface I { m(): number; }
|
||||
const o: I = { m() { throw new Error("not implemented"); } };
|
||||
@@ -0,0 +1,96 @@
|
||||
// @strict: true
|
||||
interface X {
|
||||
type: 'x';
|
||||
value: string;
|
||||
method(): void;
|
||||
}
|
||||
|
||||
interface Y {
|
||||
type: 'y';
|
||||
value: 'none' | 'done';
|
||||
method(): void;
|
||||
}
|
||||
|
||||
function foo(bar: X | Y) { }
|
||||
|
||||
foo({
|
||||
type: 'y',
|
||||
value: 'done',
|
||||
method() {
|
||||
this;
|
||||
this.type;
|
||||
this.value;
|
||||
}
|
||||
});
|
||||
|
||||
interface X2 {
|
||||
type1: 'x';
|
||||
value: string;
|
||||
method(): void;
|
||||
}
|
||||
|
||||
interface Y2 {
|
||||
type2: 'y';
|
||||
value: 'none' | 'done';
|
||||
method(): void;
|
||||
}
|
||||
|
||||
function foo2(bar: X2 | Y2) { }
|
||||
|
||||
foo2({
|
||||
type2: 'y',
|
||||
value: 'done',
|
||||
method() {
|
||||
this;
|
||||
this.value;
|
||||
}
|
||||
});
|
||||
|
||||
interface X3 {
|
||||
type: 'x';
|
||||
value: 1 | 2 | 3;
|
||||
xtra: number;
|
||||
}
|
||||
|
||||
interface Y3 {
|
||||
type: 'y';
|
||||
value: 11 | 12 | 13;
|
||||
ytra: number;
|
||||
}
|
||||
|
||||
let xy: X3 | Y3 = {
|
||||
type: 'y',
|
||||
value: 11,
|
||||
ytra: 12
|
||||
};
|
||||
|
||||
xy;
|
||||
|
||||
|
||||
interface LikeA {
|
||||
x: 'x';
|
||||
y: 'y';
|
||||
value: string;
|
||||
method(): void;
|
||||
}
|
||||
|
||||
interface LikeB {
|
||||
x: 'xx';
|
||||
y: 'yy';
|
||||
value: number;
|
||||
method(): void;
|
||||
}
|
||||
|
||||
let xyz: LikeA | LikeB = {
|
||||
x: 'x',
|
||||
y: 'y',
|
||||
value: "foo",
|
||||
method() {
|
||||
this;
|
||||
this.x;
|
||||
this.y;
|
||||
this.value;
|
||||
}
|
||||
};
|
||||
|
||||
xyz;
|
||||
@@ -0,0 +1,8 @@
|
||||
// @declaration: true
|
||||
// @filename: thingB.ts
|
||||
export interface ThingB { }
|
||||
// @filename: things.ts
|
||||
export * from "./thingB";
|
||||
// @filename: index.ts
|
||||
import * as things from "./things";
|
||||
export const thing2 = (param: things.ThingB) => null;
|
||||
@@ -0,0 +1,3 @@
|
||||
// @strictNullChecks: true
|
||||
let bar: {};
|
||||
({ ...bar } = {});
|
||||
@@ -140,14 +140,17 @@ export const o1_s2 = o1[s2];
|
||||
export const o2: T0 = o1;
|
||||
|
||||
// recursive declarations
|
||||
declare const rI: RI;
|
||||
interface RI {
|
||||
x: "a";
|
||||
// (type parameter indirection courtesy of #20400)
|
||||
declare const rI: RI<"a">;
|
||||
rI.x
|
||||
interface RI<T extends "a" | "b"> {
|
||||
x: T;
|
||||
[rI.x]: "b";
|
||||
}
|
||||
|
||||
declare const rC: RC;
|
||||
declare class RC {
|
||||
x: "a";
|
||||
declare const rC: RC<"a">;
|
||||
rC.x
|
||||
declare class RC<T extends "a" | "b"> {
|
||||
x: T;
|
||||
[rC.x]: "b";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
// @declaration: true
|
||||
// @filename: module.ts
|
||||
import * as i from "./index";
|
||||
class Foo {}
|
||||
// @filename: index.ts
|
||||
import {} from "./module";
|
||||
export interface Bar {
|
||||
x: string
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// @esModuleInterop: true
|
||||
// @filename: hybrid/index.d.ts
|
||||
export function sayHello(): string;
|
||||
// @filename: path.d.ts
|
||||
declare const anything: any;
|
||||
export = anything;
|
||||
// @filename: fs.d.ts
|
||||
declare const anything: any;
|
||||
export = anything;
|
||||
// @filename: mjts.ts
|
||||
import { sayHello } from "./hybrid";
|
||||
import path from "./path";
|
||||
import * as fs from "./fs";
|
||||
|
||||
path;
|
||||
sayHello();
|
||||
fs;
|
||||
@@ -0,0 +1,11 @@
|
||||
// @esModuleInterop: true
|
||||
// @lib: es6
|
||||
// @Filename: foo.d.ts
|
||||
declare function foo(): void;
|
||||
declare namespace foo {}
|
||||
export = foo;
|
||||
|
||||
// @Filename: index.ts
|
||||
import("./foo").then(f => {
|
||||
f.default;
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
// @esModuleInterop: true
|
||||
// @Filename: foo.d.ts
|
||||
declare function foo(): void;
|
||||
declare namespace foo {}
|
||||
export = foo;
|
||||
|
||||
// @Filename: index.ts
|
||||
import * as foo from "./foo";
|
||||
foo.default;
|
||||
@@ -0,0 +1,5 @@
|
||||
// @target: esnext
|
||||
|
||||
function* f(): Iterator<number> {
|
||||
return invalid;
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
declare class Foo {
|
||||
x: string;
|
||||
}
|
||||
declare class Bar {
|
||||
y: string;
|
||||
}
|
||||
type Wrapper = Foo & Bar;
|
||||
class Baz implements Wrapper {
|
||||
x: number;
|
||||
y: string;
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// @declaration: true
|
||||
// @filename: internal.ts
|
||||
namespace My.Internal {
|
||||
export function getThing(): void {}
|
||||
export const enum WhichThing {
|
||||
A, B, C
|
||||
}
|
||||
}
|
||||
|
||||
// @filename: usage.ts
|
||||
/// <reference path="./internal.ts" />
|
||||
namespace SomeOther.Thing {
|
||||
import Internal = My.Internal;
|
||||
export class Foo {
|
||||
private _which: Internal.WhichThing;
|
||||
constructor() {
|
||||
Internal.getThing();
|
||||
Internal.WhichThing.A ? "foo" : "bar";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
class A { a: string; }
|
||||
class B { b: string; }
|
||||
|
||||
function negativeClassesTest(x: A | B) {
|
||||
if ("a" in x) {
|
||||
x.b = "1";
|
||||
} else {
|
||||
x.a = "1";
|
||||
}
|
||||
}
|
||||
|
||||
function positiveClassesTest(x: A | B) {
|
||||
if ("a" in x) {
|
||||
x.b = "1";
|
||||
} else {
|
||||
x.a = "1";
|
||||
}
|
||||
}
|
||||
|
||||
class AWithOptionalProp { a?: string; }
|
||||
class BWithOptionalProp { b?: string; }
|
||||
|
||||
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
|
||||
if ("a" in x) {
|
||||
x.a = "1";
|
||||
} else {
|
||||
x.b = "1";
|
||||
}
|
||||
}
|
||||
|
||||
class AWithMethod {
|
||||
a(): string { return ""; }
|
||||
}
|
||||
|
||||
class BWithMethod {
|
||||
b(): string { return ""; }
|
||||
}
|
||||
|
||||
function negativeTestClassesWithMembers(x: AWithMethod | BWithMethod) {
|
||||
if ("a" in x) {
|
||||
x.a();
|
||||
x.b();
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
function negativeTestClassesWithMemberMissingInBothClasses(x: AWithMethod | BWithMethod) {
|
||||
if ("c" in x) {
|
||||
x.a();
|
||||
x.b();
|
||||
} else {
|
||||
x.a();
|
||||
x.b();
|
||||
}
|
||||
}
|
||||
|
||||
class C { a: string; }
|
||||
class D { a: string; }
|
||||
|
||||
function negativeMultipleClassesTest(x: A | B | C | D) {
|
||||
if ("a" in x) {
|
||||
x.b = "1";
|
||||
} else {
|
||||
x.a = "1";
|
||||
}
|
||||
}
|
||||
|
||||
class ClassWithUnionProp { prop: A | B }
|
||||
|
||||
function negativePropTest(x: ClassWithUnionProp) {
|
||||
if ("a" in x.prop) {
|
||||
let y: string = x.prop.b;
|
||||
} else {
|
||||
let z: string = x.prop.a;
|
||||
}
|
||||
}
|
||||
|
||||
class NegativeClassTest {
|
||||
protected prop: A | B;
|
||||
inThis() {
|
||||
if ("a" in this.prop) {
|
||||
let z: number = this.prop.b;
|
||||
} else {
|
||||
let y: string = this.prop.a;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class UnreachableCodeDetection {
|
||||
a: string;
|
||||
inThis() {
|
||||
if ("a" in this) {
|
||||
} else {
|
||||
let y = this.a;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
declare function get<U, Y extends keyof U>(x: U, y: Y): U[Y];
|
||||
declare function find<T, K extends keyof T>(o: T[K]): [T, K];
|
||||
|
||||
function impl<A, B extends keyof A>(a: A, b: B) {
|
||||
const item = get(a, b);
|
||||
return find(item);
|
||||
}
|
||||
|
||||
const o = {x: 42};
|
||||
const r = impl(o, "x");
|
||||
r[0][r[1]] = o[r[1]];
|
||||
@@ -25,4 +25,51 @@ class J {
|
||||
class K extends J {
|
||||
[n: number]: A;
|
||||
[s: string]: B;
|
||||
}
|
||||
|
||||
|
||||
type AliasedNumber = number;
|
||||
|
||||
interface L {
|
||||
[n: AliasedNumber]: A;
|
||||
}
|
||||
|
||||
type AliasedString = string;
|
||||
|
||||
interface M {
|
||||
[s: AliasedString]: A;
|
||||
}
|
||||
|
||||
type AliasedBoolean = boolean;
|
||||
|
||||
interface N {
|
||||
[b: AliasedBoolean]: A;
|
||||
}
|
||||
|
||||
type IndexableUnion = "foo" | "bar";
|
||||
|
||||
interface O {
|
||||
[u: IndexableUnion]: A;
|
||||
}
|
||||
|
||||
type NonIndexableUnion = boolean | {};
|
||||
|
||||
interface P {
|
||||
[u: NonIndexableUnion]: A;
|
||||
}
|
||||
|
||||
type NonIndexableUnion2 = string | number;
|
||||
|
||||
interface Q {
|
||||
[u: NonIndexableUnion2]: A;
|
||||
}
|
||||
|
||||
type NonIndexableUnion3 = "foo" | 42;
|
||||
|
||||
interface R {
|
||||
[u: NonIndexableUnion3]: A;
|
||||
}
|
||||
|
||||
interface S {
|
||||
[u: "foo" | "bar"]: A;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
const [, a = ''] = ''.match('') || [];
|
||||
|
||||
a.toFixed()
|
||||
@@ -0,0 +1,11 @@
|
||||
// @strictNullChecks: true
|
||||
// @jsx: react
|
||||
// @skipLibCheck: true
|
||||
// @libFiles: lib.d.ts,react.d.ts
|
||||
import * as React from "react";
|
||||
|
||||
interface Props {
|
||||
x?: "a" | "b";
|
||||
}
|
||||
class MyComponent<P extends Props = Props> extends React.Component<P, {}> {}
|
||||
const m = <MyComponent x="a"/>
|
||||
@@ -0,0 +1,20 @@
|
||||
// @jsx: react
|
||||
// @libFiles: lib.d.ts,react.d.ts
|
||||
// @skipLibCheck: true
|
||||
// @allowSyntheticDefaultImports: true
|
||||
import React from "react";
|
||||
|
||||
type InfoProps =
|
||||
| { status: "hidden" }
|
||||
| { status: "visible"; content: string };
|
||||
|
||||
const Info = (props: InfoProps) =>
|
||||
props.status === "hidden"
|
||||
? <noscript />
|
||||
: <div>{props.content}</div>;
|
||||
|
||||
const a = <Info status="hidden" />;
|
||||
const b = <Info status="visible" content="hello world" />;
|
||||
declare const infoProps: InfoProps;
|
||||
|
||||
const c = <Info {...infoProps} />;
|
||||
@@ -0,0 +1 @@
|
||||
const x: { type: string } & { type: "string" } = { type: "string" };
|
||||
@@ -1,5 +1,22 @@
|
||||
// @lib: es6, dom
|
||||
interface A { a: A }
|
||||
declare let a: A;
|
||||
type Deep<T> = { [K in keyof T]: Deep<T[K]> }
|
||||
declare function foo<T>(deep: Deep<T>): T;
|
||||
const out = foo(a);
|
||||
out.a
|
||||
out.a.a
|
||||
out.a.a.a.a.a.a.a
|
||||
|
||||
|
||||
interface B { [s: string]: B }
|
||||
declare let b: B;
|
||||
const oub = foo(b);
|
||||
oub.b
|
||||
oub.b.b
|
||||
oub.b.a.n.a.n.a
|
||||
|
||||
let xhr: XMLHttpRequest;
|
||||
const out2 = foo(xhr);
|
||||
out2.responseXML
|
||||
out2.responseXML.activeElement.className.length
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
interface Foo {
|
||||
bold(): string;
|
||||
}
|
||||
|
||||
interface Foo {
|
||||
bold: string;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
class T<A> {
|
||||
a: A;
|
||||
b: any
|
||||
}
|
||||
class L<RT extends { a: 'a' | 'b', b: any }> extends T<RT[RT['a']]> {
|
||||
m() { this.a }
|
||||
}
|
||||
class X extends L<X> {
|
||||
a: 'a' | 'b'
|
||||
b: number
|
||||
m2() {
|
||||
this.a
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// https://github.com/Microsoft/TypeScript/issues/19632
|
||||
declare function direct<A extends string>(a: A | A[]): Record<A, string>
|
||||
declare function nested<A extends string>(a: { fields: A }): Record<A, string>
|
||||
declare function nestedUnion<A extends string>(a: { fields: A | A[] }): Record<A, string>
|
||||
|
||||
const directUnionSingle = direct("z")
|
||||
const directUnionArray = direct(["z", "y"])
|
||||
const nestedSingle = nested({fields: "z"})
|
||||
const nestedUnionSingle = nestedUnion({fields: "z"})
|
||||
const nestedUnionArray = nestedUnion({fields: ["z", "y"]})
|
||||
|
||||
declare function hasZField(arg: { z: string }): void
|
||||
|
||||
hasZField(directUnionSingle) // ok
|
||||
hasZField(directUnionArray) // ok
|
||||
hasZField(nestedSingle) // ok
|
||||
hasZField(nestedUnionSingle) // ok
|
||||
hasZField(nestedUnionArray) // ok
|
||||
@@ -0,0 +1,18 @@
|
||||
// @noUnusedLocals: true
|
||||
|
||||
namespace n {
|
||||
function f() {
|
||||
f;
|
||||
}
|
||||
|
||||
switch (0) {
|
||||
case 0:
|
||||
function g() {
|
||||
g;
|
||||
}
|
||||
default:
|
||||
function h() {
|
||||
h;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// @noUnusedLocals: true
|
||||
// @lib: es6
|
||||
|
||||
const x = Symbol("x");
|
||||
const y = Symbol("y");
|
||||
class C {
|
||||
private [x]: number;
|
||||
private [y]: number;
|
||||
m() {
|
||||
this[x] = 0; // write-only
|
||||
this[y];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
// @strictNullChecks: true
|
||||
|
||||
null();
|
||||
undefined();
|
||||
let f: null | undefined;
|
||||
f();
|
||||
@@ -0,0 +1,3 @@
|
||||
Boolean({
|
||||
x: 0,,
|
||||
});
|
||||
@@ -0,0 +1,3 @@
|
||||
class C {
|
||||
type!: number;
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// @jsx: preserve
|
||||
|
||||
|
||||
namespace JSX {
|
||||
export interface IntrinsicElements {
|
||||
span: {};
|
||||
}
|
||||
export interface Element {
|
||||
something?: any;
|
||||
}
|
||||
}
|
||||
|
||||
const Foo = (props: { foo: "A" | "B" | "C" }) => <span>{props.foo}</span>;
|
||||
|
||||
Foo({
|
||||
foo: "B"
|
||||
});
|
||||
|
||||
<Foo foo="B" />
|
||||
@@ -0,0 +1,3 @@
|
||||
declare function f<T>(predicate: (x: {}) => x is T): T;
|
||||
// 'res' should be of type 'number'.
|
||||
const res = f((n): n is number => true);
|
||||
@@ -0,0 +1,3 @@
|
||||
[true, true, false, null]
|
||||
.filter((thing): thing is boolean => thing !== null)
|
||||
.map(thing => thing.toString());
|
||||
@@ -0,0 +1,14 @@
|
||||
interface A {
|
||||
pred(x: {}): x is boolean;
|
||||
}
|
||||
interface B {
|
||||
pred(x: {}): x is string;
|
||||
}
|
||||
|
||||
type Or = A | B;
|
||||
|
||||
function f(o: Or, x: {}) {
|
||||
if (o.pred(x)) {
|
||||
x;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
declare function isString(x: any): x is string;
|
||||
declare function isNumber(x: any): x is number;
|
||||
declare function f(p: typeof isString | typeof isNumber): void;
|
||||
f(isString);
|
||||
f(isNumber);
|
||||
@@ -0,0 +1,15 @@
|
||||
interface A {
|
||||
pred(x: {}, y: {}): x is boolean;
|
||||
}
|
||||
interface B {
|
||||
pred(x: {}, y: {}): y is string;
|
||||
}
|
||||
|
||||
type Or = A | B;
|
||||
|
||||
function f(o: Or, x: {}, y: {}) {
|
||||
if (o.pred(x, y)) {
|
||||
x;
|
||||
y;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// @strict: true
|
||||
|
||||
// Repro from #20802
|
||||
|
||||
function x<T>(ctor: {
|
||||
(this: {}, v: T): void;
|
||||
new(v: T): void;
|
||||
} | {
|
||||
(v: T): void;
|
||||
new(v: T): void;
|
||||
}, t: T) {
|
||||
new ctor(t);
|
||||
}
|
||||
@@ -5,7 +5,9 @@
|
||||
class Employee {
|
||||
private _fullName: string;
|
||||
|
||||
get fullName(): string {
|
||||
private get fullName(): string {
|
||||
return this._fullName;
|
||||
}
|
||||
// Will not also error on the setter
|
||||
private set fullName(_: string) {}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
class Employee {
|
||||
private _fullName: string;
|
||||
|
||||
set fullName(newName: string) {
|
||||
private set fullName(newName: string) {
|
||||
this._fullName = newName;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// @noUnusedLocals:true
|
||||
|
||||
// Unlike everything else, a setter without a getter is used by a write access.
|
||||
class Employee {
|
||||
private set p(_: number) {}
|
||||
|
||||
m() {
|
||||
this.p = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
const enum TestType { foo, bar }
|
||||
type TestTypeStr = keyof typeof TestType;
|
||||
|
||||
function f1(f: TestType) { }
|
||||
function f2(f: TestTypeStr) { }
|
||||
|
||||
f1(TestType.foo)
|
||||
f1(TestType.bar)
|
||||
f2('foo')
|
||||
f2('bar')
|
||||
@@ -0,0 +1,10 @@
|
||||
// @strictNullChecks: true
|
||||
declare const envVar: string | undefined;
|
||||
if (typeof envVar === `string`) {
|
||||
envVar.slice(0)
|
||||
}
|
||||
|
||||
declare const obj: {test: string} | {}
|
||||
if (`test` in obj) {
|
||||
obj.test.slice(0)
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
// @strict: true
|
||||
|
||||
// Repro from #20840
|
||||
|
||||
function function1<T extends 'a' | 'b'>(key: T) {
|
||||
switch (key) {
|
||||
case 'a':
|
||||
key.toLowerCase();
|
||||
break;
|
||||
default:
|
||||
key.toLowerCase();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -10,5 +10,4 @@ import(...["PathModule"]);
|
||||
|
||||
var p1 = import(...a);
|
||||
const p2 = import();
|
||||
const p3 = import(,);
|
||||
const p4 = import("pathToModule", "secondModule");
|
||||
@@ -7,7 +7,7 @@ for (var x of Object.values(o)) {
|
||||
let y = x;
|
||||
}
|
||||
|
||||
var entries = Object.entries(o); // <-- entries: ['a' | 'b', number][]
|
||||
var entries1 = Object.entries(1); // <-- entries: [string, any][]
|
||||
var entries2 = Object.entries({a: true, b: 2}) // ['a' | 'b', number | boolean][]
|
||||
var entries3 = Object.entries({}) // [never, any][]
|
||||
var entries = Object.entries(o);
|
||||
var entries1 = Object.entries(1);
|
||||
var entries2 = Object.entries({a: true, b: 2})
|
||||
var entries3 = Object.entries({})
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
class A { a: string; }
|
||||
class B { b: number; }
|
||||
class C { b: Object; }
|
||||
class D { a: Date; }
|
||||
|
||||
function namedClasses(x: A | B) {
|
||||
if ("a" in x) {
|
||||
x.a = "1";
|
||||
} else {
|
||||
x.b = 1;
|
||||
}
|
||||
}
|
||||
|
||||
function multipleClasses(x: A | B | C | D) {
|
||||
if ("a" in x) {
|
||||
let y: string | Date = x.a;
|
||||
} else {
|
||||
let z: number | Object = x.b;
|
||||
}
|
||||
}
|
||||
|
||||
function anonymousClasses(x: { a: string; } | { b: number; }) {
|
||||
if ("a" in x) {
|
||||
let y: string = x.a;
|
||||
} else {
|
||||
let z: number = x.b;
|
||||
}
|
||||
}
|
||||
|
||||
class AWithOptionalProp { a?: string; }
|
||||
class BWithOptionalProp { b?: string; }
|
||||
|
||||
function positiveTestClassesWithOptionalProperties(x: AWithOptionalProp | BWithOptionalProp) {
|
||||
if ("a" in x) {
|
||||
x.a = "1";
|
||||
} else {
|
||||
const y: string = x instanceof AWithOptionalProp
|
||||
? x.a
|
||||
: x.b
|
||||
}
|
||||
}
|
||||
|
||||
function inParenthesizedExpression(x: A | B) {
|
||||
if ("a" in (x)) {
|
||||
let y: string = x.a;
|
||||
} else {
|
||||
let z: number = x.b;
|
||||
}
|
||||
}
|
||||
|
||||
class ClassWithUnionProp { prop: A | B; }
|
||||
|
||||
function inProperty(x: ClassWithUnionProp) {
|
||||
if ("a" in x.prop) {
|
||||
let y: string = x.prop.a;
|
||||
} else {
|
||||
let z: number = x.prop.b;
|
||||
}
|
||||
}
|
||||
|
||||
class NestedClassWithProp { outer: ClassWithUnionProp; }
|
||||
|
||||
function innestedProperty(x: NestedClassWithProp) {
|
||||
if ("a" in x.outer.prop) {
|
||||
let y: string = x.outer.prop.a;
|
||||
} else {
|
||||
let z: number = x.outer.prop.b;
|
||||
}
|
||||
}
|
||||
|
||||
class InMemberOfClass {
|
||||
protected prop: A | B;
|
||||
inThis() {
|
||||
if ("a" in this.prop) {
|
||||
let y: string = this.prop.a;
|
||||
} else {
|
||||
let z: number = this.prop.b;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// added for completeness
|
||||
class SelfAssert {
|
||||
a: string;
|
||||
inThis() {
|
||||
if ("a" in this) {
|
||||
let y: string = this.a;
|
||||
} else {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface Indexed {
|
||||
[s: string]: any;
|
||||
}
|
||||
|
||||
function f(i: Indexed) {
|
||||
if ("a" in i) {
|
||||
return i.a;
|
||||
}
|
||||
else if ("b" in i) {
|
||||
return i.b;
|
||||
}
|
||||
return "c" in i && i.c;
|
||||
}
|
||||
@@ -296,6 +296,9 @@ define(function () {
|
||||
|
||||
isArray = ('isArray' in Array) ?
|
||||
Array.isArray : function (value) { return Object.prototype.toString.call(value) === '[object Array]'; };
|
||||
isArray = 'isArray' in Array
|
||||
? function (value) { return Object.prototype.toString.call(value) === '[object Array]'; }
|
||||
: Array.isArray;
|
||||
|
||||
function equalIC(a, b) {
|
||||
return a != null && b != null && a.toLowerCase() === b.toLowerCase();
|
||||
@@ -966,7 +969,7 @@ define(function () {
|
||||
|
||||
// should not be replaced by a completely new object - just overwrite existing methods
|
||||
MobileDetect._impl = impl;
|
||||
|
||||
|
||||
MobileDetect.version = '1.3.3 2016-07-31';
|
||||
|
||||
return MobileDetect;
|
||||
|
||||
+21
-1
@@ -38,4 +38,24 @@ module M3 {
|
||||
export interface A<T extends Number> { // error
|
||||
y: T;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface B<T extends number> {
|
||||
u: T;
|
||||
v: Constraint<T>; // ok
|
||||
}
|
||||
|
||||
interface B<T> { // ok
|
||||
x: T;
|
||||
y: Constraint<T>; // ok
|
||||
}
|
||||
|
||||
interface C<T> {
|
||||
x: T;
|
||||
}
|
||||
|
||||
interface C<T extends number> { // error
|
||||
y: T;
|
||||
}
|
||||
|
||||
interface Constraint<T extends number> {}
|
||||
|
||||
@@ -13,7 +13,6 @@ class B1<T extends { x: string }> extends React.Component<T, {}> {
|
||||
}
|
||||
class B<U> extends React.Component<U, {}> {
|
||||
render() {
|
||||
// Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object
|
||||
return <B1 {...this.props} x="hi" />;
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,6 @@ class B1<T extends { x: string }> extends React.Component<T, {}> {
|
||||
class B<U> extends React.Component<U, {}> {
|
||||
props: U;
|
||||
render() {
|
||||
// Should be an ok but as of 2.3.3 this will be an error as we will instantiate B1.props to be empty object
|
||||
return <B1 {...this.props} x="hi" />;
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,5 @@ declare class MyComp<P = Prop> extends React.Component<P, {}> {
|
||||
internalProp: P;
|
||||
}
|
||||
|
||||
// Error
|
||||
let x = <MyComp />
|
||||
let x1 = <MyComp a="hi"/>
|
||||
@@ -15,9 +15,11 @@ declare class MyComp<P extends Prop> extends React.Component<P, {}> {
|
||||
internalProp: P;
|
||||
}
|
||||
|
||||
// OK: we fille in missing type argument with empty object
|
||||
// Error
|
||||
let x1 = <MyComp />
|
||||
|
||||
// Error
|
||||
// OK
|
||||
let x = <MyComp a={10} b="hi" />
|
||||
|
||||
// Error
|
||||
let x2 = <MyComp a="hi"/>
|
||||
@@ -3,6 +3,7 @@
|
||||
// @module: amd
|
||||
// @noLib: true
|
||||
// @strictNullChecks: true
|
||||
// @skipLibCheck: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react');
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
// @module: amd
|
||||
// @noLib: true
|
||||
// @strictNullChecks: true
|
||||
// @skipLibCheck: true
|
||||
// @libFiles: react.d.ts,lib.d.ts
|
||||
|
||||
import React = require('react');
|
||||
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
0b00_11;
|
||||
0B0_1;
|
||||
0b1100_0011;
|
||||
0B0_11_0101;
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// @filename: 1.ts
|
||||
0b00_
|
||||
|
||||
// @filename: 2.ts
|
||||
0b_110
|
||||
|
||||
// @filename: 3.ts
|
||||
0_B0101
|
||||
|
||||
// @filename: 4.ts
|
||||
0b01__11
|
||||
|
||||
// @filename: 5.ts
|
||||
|
||||
0B0110_0110__
|
||||
|
||||
// @filename: 6.ts
|
||||
0b___0111010_0101_1
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
1_000_000_000
|
||||
1.1_00_01
|
||||
1e1_0
|
||||
1e+1_0
|
||||
1e-1_0
|
||||
1.1e10_0
|
||||
1.1e+10_0
|
||||
1.1e-10_0
|
||||
12_34_56
|
||||
1_22_333
|
||||
1_2.3_4
|
||||
1_2.3_4e5_6
|
||||
1_2.3_4e+5_6
|
||||
1_2.3_4e-5_6
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
// @filename: 1.ts
|
||||
_10
|
||||
|
||||
// @filename: 2.ts
|
||||
10_
|
||||
|
||||
// @filename: 3.ts
|
||||
1__0
|
||||
|
||||
// @filename: 4.ts
|
||||
0_.0
|
||||
|
||||
// @filename: 5.ts
|
||||
0._0
|
||||
|
||||
// @filename: 6.ts
|
||||
0.0__0
|
||||
|
||||
// @filename: 7.ts
|
||||
0.0__
|
||||
|
||||
// @filename: 8.ts
|
||||
0_e0
|
||||
|
||||
// @filename: 9.ts
|
||||
0e_0
|
||||
|
||||
// @filename: 10.ts
|
||||
0e0_
|
||||
|
||||
// @filename: 11.ts
|
||||
0e0__0
|
||||
|
||||
// @filename: 12.ts
|
||||
0_.0e0
|
||||
|
||||
// @filename: 13.ts
|
||||
0._0e0
|
||||
|
||||
// @filename: 14.ts
|
||||
0.0_e0
|
||||
|
||||
// @filename: 15.ts
|
||||
0.0e_0
|
||||
|
||||
// @filename: 16.ts
|
||||
_0.0e0
|
||||
|
||||
// @filename: 17.ts
|
||||
0.0e0_
|
||||
|
||||
// @filename: 18.ts
|
||||
0__0.0e0
|
||||
|
||||
// @filename: 19.ts
|
||||
0.0__0e0
|
||||
|
||||
// @filename: 20.ts
|
||||
0.00e0__0
|
||||
|
||||
// @filename: 21.ts
|
||||
0_e+0
|
||||
|
||||
// @filename: 22.ts
|
||||
0e+_0
|
||||
|
||||
// @filename: 23.ts
|
||||
0e+0_
|
||||
|
||||
// @filename: 24.ts
|
||||
0e+0__0
|
||||
|
||||
// @filename: 25.ts
|
||||
0_.0e+0
|
||||
|
||||
// @filename: 26.ts
|
||||
0._0e+0
|
||||
|
||||
// @filename: 27.ts
|
||||
0.0_e+0
|
||||
|
||||
// @filename: 28.ts
|
||||
0.0e+_0
|
||||
|
||||
// @filename: 29.ts
|
||||
_0.0e+0
|
||||
|
||||
// @filename: 30.ts
|
||||
0.0e+0_
|
||||
|
||||
// @filename: 31.ts
|
||||
0__0.0e+0
|
||||
|
||||
// @filename: 32.ts
|
||||
0.0__0e+0
|
||||
|
||||
// @filename: 33.ts
|
||||
0.00e+0__0
|
||||
|
||||
// @filename: 34.ts
|
||||
0_e+0
|
||||
|
||||
// @filename: 35.ts
|
||||
0e-_0
|
||||
|
||||
// @filename: 36.ts
|
||||
0e-0_
|
||||
|
||||
// @filename: 37.ts
|
||||
0e-0__0
|
||||
|
||||
// @filename: 38.ts
|
||||
0_.0e-0
|
||||
|
||||
// @filename: 39.ts
|
||||
0._0e-0
|
||||
|
||||
// @filename: 40.ts
|
||||
0.0_e-0
|
||||
|
||||
// @filename: 41.ts
|
||||
0.0e-_0
|
||||
|
||||
// @filename: 42.ts
|
||||
_0.0e-0
|
||||
|
||||
// @filename: 43.ts
|
||||
0.0e-0_
|
||||
|
||||
// @filename: 44.ts
|
||||
0__0.0e-0
|
||||
|
||||
// @filename: 45.ts
|
||||
0.0__0e-0
|
||||
|
||||
// @filename: 46.ts
|
||||
0.00e-0__0
|
||||
|
||||
// @filename: 47.ts
|
||||
._
|
||||
|
||||
// @filename: 48.ts
|
||||
1\u005F01234
|
||||
|
||||
// @filename: 49.ts
|
||||
1.0e_+10
|
||||
|
||||
// @filename: 50.ts
|
||||
1.0e_-10
|
||||
|
||||
// @filename: 51.ts
|
||||
0._
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
0x00_11;
|
||||
0X0_1;
|
||||
0x1100_0011;
|
||||
0X0_11_0101;
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// @filename: 1.ts
|
||||
0x00_
|
||||
|
||||
// @filename: 2.ts
|
||||
0x_110
|
||||
|
||||
// @filename: 3.ts
|
||||
0_X0101
|
||||
|
||||
// @filename: 4.ts
|
||||
0x01__11
|
||||
|
||||
// @filename: 5.ts
|
||||
|
||||
0X0110_0110__
|
||||
|
||||
// @filename: 6.ts
|
||||
0x___0111010_0101_1
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
0o00_11;
|
||||
0O0_1;
|
||||
0o1100_0011;
|
||||
0O0_11_0101;
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
// @filename: 1.ts
|
||||
0o00_
|
||||
|
||||
// @filename: 2.ts
|
||||
0o_110
|
||||
|
||||
// @filename: 3.ts
|
||||
0_O0101
|
||||
|
||||
// @filename: 4.ts
|
||||
0o01__11
|
||||
|
||||
// @filename: 5.ts
|
||||
|
||||
0O0110_0110__
|
||||
|
||||
// @filename: 6.ts
|
||||
0o___0111010_0101_1
|
||||
+143
@@ -0,0 +1,143 @@
|
||||
// @filename: 1.ts
|
||||
"\u{10_ffff}"
|
||||
|
||||
// @filename: 2.ts
|
||||
'\u{10_ffff}'
|
||||
|
||||
// @filename: 3.ts
|
||||
`\u{10_ffff}`
|
||||
|
||||
// @filename: 4.ts
|
||||
/\u{10_ffff}/u
|
||||
|
||||
// @filename: 5.ts
|
||||
"\uff_ff"
|
||||
|
||||
// @filename: 6.ts
|
||||
'\uff_ff'
|
||||
|
||||
// @filename: 7.ts
|
||||
`\uff_ff`
|
||||
|
||||
// @filename: 8.ts
|
||||
/\uff_ff/u
|
||||
|
||||
// @filename: 9.ts
|
||||
"\xf_f"
|
||||
|
||||
// @filename: 10.ts
|
||||
'\xf_f'
|
||||
|
||||
// @filename: 11.ts
|
||||
`\xf_f`
|
||||
|
||||
// @filename: 12.ts
|
||||
/\xf_f/u
|
||||
|
||||
// @filename: 13.ts
|
||||
"\u{_10ffff}"
|
||||
|
||||
// @filename: 14.ts
|
||||
'\u{_10ffff}'
|
||||
|
||||
// @filename: 15.ts
|
||||
`\u{_10ffff}`
|
||||
|
||||
// @filename: 16.ts
|
||||
/\u{_10ffff}/u
|
||||
|
||||
// @filename: 17.ts
|
||||
"\u_ffff"
|
||||
|
||||
// @filename: 18.ts
|
||||
'\u_ffff'
|
||||
|
||||
// @filename: 19.ts
|
||||
`\u_ffff`
|
||||
|
||||
// @filename: 20.ts
|
||||
/\u_ffff/u
|
||||
|
||||
// @filename: 21.ts
|
||||
"\x_ff"
|
||||
|
||||
// @filename: 22.ts
|
||||
'\x_ff'
|
||||
|
||||
// @filename: 23.ts
|
||||
`\x_ff`
|
||||
|
||||
// @filename: 24.ts
|
||||
/\x_ff/u
|
||||
|
||||
// @filename: 25.ts
|
||||
"\u{10ffff_}"
|
||||
|
||||
// @filename: 26.ts
|
||||
'\u{10ffff_}'
|
||||
|
||||
// @filename: 27.ts
|
||||
`\u{10ffff_}`
|
||||
|
||||
// @filename: 28.ts
|
||||
/\u{10ffff_}/u
|
||||
|
||||
// @filename: 29.ts
|
||||
"\uffff_"
|
||||
|
||||
// @filename: 30.ts
|
||||
'\uffff_'
|
||||
|
||||
// @filename: 31.ts
|
||||
`\uffff_`
|
||||
|
||||
// @filename: 32.ts
|
||||
/\uffff_/u
|
||||
|
||||
// @filename: 33.ts
|
||||
"\xff_"
|
||||
|
||||
// @filename: 34.ts
|
||||
'\xff_'
|
||||
|
||||
// @filename: 35.ts
|
||||
`\xff_`
|
||||
|
||||
// @filename: 36.ts
|
||||
/\xff_/u
|
||||
|
||||
// @filename: 37.ts
|
||||
"\u{10__ffff}"
|
||||
|
||||
// @filename: 38.ts
|
||||
'\u{10__ffff}'
|
||||
|
||||
// @filename: 39.ts
|
||||
`\u{10__ffff}`
|
||||
|
||||
// @filename: 40.ts
|
||||
/\u{10__ffff}/u
|
||||
|
||||
// @filename: 41.ts
|
||||
"\uff__ff"
|
||||
|
||||
// @filename: 42.ts
|
||||
'\uff__ff'
|
||||
|
||||
// @filename: 43.ts
|
||||
`\uff__ff`
|
||||
|
||||
// @filename: 44.ts
|
||||
/\uff__ff/u
|
||||
|
||||
// @filename: 45.ts
|
||||
"\xf__f"
|
||||
|
||||
// @filename: 46.ts
|
||||
'\xf__f'
|
||||
|
||||
// @filename: 47.ts
|
||||
`\xf__f`
|
||||
|
||||
// @filename: 48.ts
|
||||
/\xf__f/u
|
||||
@@ -0,0 +1,16 @@
|
||||
// @noEmit: true
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
// @target: es3
|
||||
// @filename: index.js
|
||||
Common.Item = class I {}
|
||||
Common.Object = class extends Common.Item {}
|
||||
|
||||
Workspace.Object = class extends Common.Object {}
|
||||
|
||||
/** @type {Workspace.Object} */
|
||||
var am;
|
||||
|
||||
// @filename: roots.js
|
||||
var Common = {};
|
||||
var Workspace = {};
|
||||
@@ -0,0 +1,2 @@
|
||||
declare let o: object;
|
||||
const x: { a: number, b: number } = { a: 1, ...o, b: 2 };
|
||||
@@ -12,5 +12,5 @@
|
||||
const ranges = test.ranges();
|
||||
const [r0, r1] = ranges;
|
||||
// TODO: Want these to be in the same group, but that would require creating a symbol for `x`.
|
||||
verify.singleReferenceGroup("import x", [r0]);
|
||||
verify.singleReferenceGroup("import x", [r1]);
|
||||
verify.singleReferenceGroup("(alias) module \"jquery\"\nimport x", [r0]);
|
||||
verify.singleReferenceGroup("(alias) module \"jquery\"\nimport x", [r1]);
|
||||
@@ -10,22 +10,22 @@
|
||||
////import [|/*importBang*/bang|] = require("jquery");
|
||||
////[|foo/*useFoo*/|]([|bar/*useBar*/|], [|baz/*useBaz*/|], [|bang/*useBang*/|]);
|
||||
|
||||
verify.quickInfoAt("useFoo", "import foo");
|
||||
verify.quickInfoAt("useFoo", "(alias) module \"jquery\"\nimport foo");
|
||||
verify.goToDefinition({
|
||||
useFoo: "module",
|
||||
importFoo: "module"
|
||||
});
|
||||
|
||||
verify.quickInfoAt("useBar", "import bar");
|
||||
verify.quickInfoAt("useBar", "(alias) module \"jquery\"\nimport bar");
|
||||
verify.goToDefinition("useBar", "module");
|
||||
|
||||
verify.quickInfoAt("useBaz", "import baz");
|
||||
verify.quickInfoAt("useBaz", "(alias) module \"jquery\"\nimport baz");
|
||||
verify.goToDefinition({
|
||||
useBaz: "importBaz",
|
||||
importBaz: "module"
|
||||
});
|
||||
|
||||
verify.quickInfoAt("useBang", "import bang = require(\"jquery\")");
|
||||
verify.quickInfoAt("useBang", "(alias) module \"jquery\"\nimport bang = require(\"jquery\")");
|
||||
verify.goToDefinition({
|
||||
useBang: "module",
|
||||
importBang: "module"
|
||||
|
||||
@@ -36,8 +36,5 @@ function checkRefs() {
|
||||
const ranges = test.ranges();
|
||||
const [r0, r1] = ranges;
|
||||
verify.referenceGroups(r0, [{ definition: "(method) Test.start(): this", ranges }]);
|
||||
verify.referenceGroups(r1, [
|
||||
{ definition: "(method) Second.Test.start(): Second.Test", ranges: [r0] },
|
||||
{ definition: "(method) Second.Test.start(): Second.Test", ranges: [r1] }
|
||||
]);
|
||||
verify.referenceGroups(r1, [{ definition: "(method) Second.Test.start(): Second.Test", ranges }]);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////declare function foo(): (...args: any[]) => void;
|
||||
////class C {
|
||||
//// @foo
|
||||
//// bar() {}
|
||||
////
|
||||
//// @foo
|
||||
//// baz() {}
|
||||
////}
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "addMissingInvocationForDecorator",
|
||||
newFileContent:
|
||||
`declare function foo(): (...args: any[]) => void;
|
||||
class C {
|
||||
@foo()
|
||||
bar() {}
|
||||
|
||||
@foo()
|
||||
baz() {}
|
||||
}`
|
||||
});
|
||||
@@ -17,7 +17,7 @@ verify.codeFix({
|
||||
index: 0,
|
||||
// TODO: GH#18445
|
||||
newFileContent: `class C {
|
||||
constructor() {
|
||||
constructor() {\r
|
||||
this.foo = undefined;\r
|
||||
}
|
||||
method() {
|
||||
|
||||
@@ -15,7 +15,7 @@ verify.codeFix({
|
||||
index: 0,
|
||||
// TODO: GH#18445
|
||||
newFileContent: `class C {
|
||||
constructor() {
|
||||
constructor() {\r
|
||||
this.foo = undefined;\r
|
||||
}
|
||||
prop = ()=>{ this.foo === 10 };
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////class C {
|
||||
//// method() {
|
||||
//// this.x = 0;
|
||||
//// this.y();
|
||||
//// this.x = "";
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "addMissingMember",
|
||||
newFileContent:
|
||||
// TODO: GH#18445
|
||||
`class C {
|
||||
x: number;\r
|
||||
y(): any {\r
|
||||
throw new Error("Method not implemented.");\r
|
||||
}\r
|
||||
method() {
|
||||
this.x = 0;
|
||||
this.y();
|
||||
this.x = "";
|
||||
}
|
||||
}`,
|
||||
});
|
||||
@@ -0,0 +1,33 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
// @allowJs: true
|
||||
// @checkJs: true
|
||||
|
||||
// @Filename: /a.js
|
||||
////class C {
|
||||
//// constructor() {}
|
||||
//// method() {
|
||||
//// this.x;
|
||||
//// this.y();
|
||||
//// this.x;
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "addMissingMember",
|
||||
newFileContent:
|
||||
// TODO: GH#18445
|
||||
`class C {
|
||||
y() {\r
|
||||
throw new Error("Method not implemented.");\r
|
||||
}\r
|
||||
constructor() {\r
|
||||
this.x = undefined;\r
|
||||
}
|
||||
method() {
|
||||
this.x;
|
||||
this.y();
|
||||
this.x;
|
||||
}
|
||||
}`,
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function f() {
|
||||
//// await Promise.resolve();
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: "Add async modifier to containing function",
|
||||
newFileContent:
|
||||
`async function f() {
|
||||
await Promise.resolve();
|
||||
}`,
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////const f: () => number | string = () => {
|
||||
//// await Promise.resolve('foo');
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: "Add async modifier to containing function",
|
||||
newFileContent:
|
||||
`const f: () => Promise<number | string> = async () => {
|
||||
await Promise.resolve('foo');
|
||||
}`,
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////const f: string = () => {
|
||||
//// await Promise.resolve('foo');
|
||||
////}
|
||||
|
||||
// should not change type if it's incorrectly set
|
||||
verify.codeFix({
|
||||
description: "Add async modifier to containing function",
|
||||
newFileContent:
|
||||
`const f: string = async () => {
|
||||
await Promise.resolve('foo');
|
||||
}`,
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////const f: () => Array<number | string> = function() {
|
||||
//// await Promise.resolve([]);
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: "Add async modifier to containing function",
|
||||
newFileContent:
|
||||
`const f: () => Promise<Array<number | string>> = async function() {
|
||||
await Promise.resolve([]);
|
||||
}`,
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////const f: () => Promise<number | string> = () => {
|
||||
//// await Promise.resolve('foo');
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: "Add async modifier to containing function",
|
||||
newFileContent:
|
||||
`const f: () => Promise<number | string> = async () => {
|
||||
await Promise.resolve('foo');
|
||||
}`,
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////const f = function(): number {
|
||||
//// await Promise.resolve(1);
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: "Add async modifier to containing function",
|
||||
newFileContent:
|
||||
`const f = async function(): Promise<number> {
|
||||
await Promise.resolve(1);
|
||||
}`,
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////const f = (): number[] => {
|
||||
//// await Promise.resolve([1]);
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: "Add async modifier to containing function",
|
||||
newFileContent:
|
||||
`const f = async (): Promise<number[]> => {
|
||||
await Promise.resolve([1]);
|
||||
}`,
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////const f = function() {
|
||||
//// await Promise.resolve();
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: "Add async modifier to containing function",
|
||||
newFileContent:
|
||||
`const f = async function() {
|
||||
await Promise.resolve();
|
||||
}`,
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////const f = {
|
||||
//// get a() {
|
||||
//// return await Promise.resolve();
|
||||
//// },
|
||||
//// get a() {
|
||||
//// await Promise.resolve();
|
||||
//// },
|
||||
////}
|
||||
|
||||
verify.not.codeFixAvailable();
|
||||
@@ -0,0 +1,9 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////class Foo {
|
||||
//// constructor {
|
||||
//// await Promise.resolve();
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.not.codeFixAvailable();
|
||||
@@ -0,0 +1,17 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////class Foo {
|
||||
//// bar() {
|
||||
//// await Promise.resolve();
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: "Add async modifier to containing function",
|
||||
newFileContent:
|
||||
`class Foo {
|
||||
async bar() {
|
||||
await Promise.resolve();
|
||||
}
|
||||
}`,
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////const f = promise => {
|
||||
//// await promise;
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: "Add async modifier to containing function",
|
||||
newFileContent:
|
||||
`const f = async promise => {
|
||||
await promise;
|
||||
}`,
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////const f = (promise) => {
|
||||
//// await promise;
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: "Add async modifier to containing function",
|
||||
newFileContent:
|
||||
`const f = async (promise) => {
|
||||
await promise;
|
||||
}`,
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function f() {
|
||||
//// for await (const x of g()) {
|
||||
//// console.log(x);
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: "Add async modifier to containing function",
|
||||
newFileContent:
|
||||
`async function f() {
|
||||
for await (const x of g()) {
|
||||
console.log(x);
|
||||
}
|
||||
}`,
|
||||
});
|
||||
@@ -0,0 +1,13 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function f(): number | string {
|
||||
//// await Promise.resolve(8);
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: "Add async modifier to containing function",
|
||||
newFileContent:
|
||||
`async function f(): Promise<number | string> {
|
||||
await Promise.resolve(8);
|
||||
}`,
|
||||
});
|
||||
@@ -0,0 +1,17 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////class Foo {
|
||||
//// bar(): string {
|
||||
//// await Promise.resolve('baz');
|
||||
//// }
|
||||
////}
|
||||
|
||||
verify.codeFix({
|
||||
description: "Add async modifier to containing function",
|
||||
newFileContent:
|
||||
`class Foo {
|
||||
async bar(): Promise<string> {
|
||||
await Promise.resolve('baz');
|
||||
}
|
||||
}`,
|
||||
});
|
||||
@@ -0,0 +1,21 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
|
||||
////function f() {
|
||||
//// await Promise.resolve();
|
||||
////}
|
||||
////
|
||||
////const g = () => {
|
||||
//// await f();
|
||||
////}
|
||||
|
||||
verify.codeFixAll({
|
||||
fixId: "fixAwaitInSyncFunction",
|
||||
newFileContent:
|
||||
`async function f() {
|
||||
await Promise.resolve();
|
||||
}
|
||||
|
||||
const g = async () => {
|
||||
await f();
|
||||
}`,
|
||||
});
|
||||
@@ -0,0 +1,18 @@
|
||||
/// <reference path='fourslash.ts' />
|
||||
// @esModuleInterop: true
|
||||
// @Filename: foo.d.ts
|
||||
////declare function foo(): void;
|
||||
////declare namespace foo {}
|
||||
////export = foo;
|
||||
|
||||
// @Filename: index.ts
|
||||
////[|import * as foo from "./foo";|]
|
||||
////function invoke(f: () => void) { f(); }
|
||||
////invoke(foo);
|
||||
|
||||
goTo.file(1);
|
||||
verify.codeFix({
|
||||
description: `Replace import with 'import foo = require("./foo");'.`,
|
||||
newRangeContent: `import foo = require("./foo");`,
|
||||
index: 1,
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user