Merge pull request #20711 from Microsoft/defer-inference-for-recursive-mapped-types

Defer inference for homomorphic mapped types
This commit is contained in:
Nathan Shively-Sanders authored and GitHub committed 2018-01-05 16:01:26 -08:00
commit e78ac47208
17 files changed
+434 -104

No files matched your search

+67 -40
View File
@@ -339,6 +339,7 @@ namespace ts {
const jsObjectLiteralIndexInfo = createIndexInfo(anyType, /*isReadonly*/ false);
const globals = createSymbolTable();
const reverseMappedCache = createMap<Type | undefined>();
let ambientModulesCache: Symbol[] | undefined;
/**
* List of every ambient module with a "*" wildcard.
@@ -2860,7 +2861,10 @@ namespace ts {
typeElements.push(<ConstructSignatureDeclaration>signatureToSignatureDeclarationHelper(signature, SyntaxKind.ConstructSignature, context));
}
if (resolvedType.stringIndexInfo) {
typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.stringIndexInfo, IndexKind.String, context));
const indexInfo = resolvedType.objectFlags & ObjectFlags.ReverseMapped ?
createIndexInfo(anyType, resolvedType.stringIndexInfo.isReadonly, resolvedType.stringIndexInfo.declaration) :
resolvedType.stringIndexInfo;
typeElements.push(indexInfoToIndexSignatureDeclarationHelper(indexInfo, IndexKind.String, context));
}
if (resolvedType.numberIndexInfo) {
typeElements.push(indexInfoToIndexSignatureDeclarationHelper(resolvedType.numberIndexInfo, IndexKind.Number, context));
@@ -2872,7 +2876,7 @@ namespace ts {
}
for (const propertySymbol of properties) {
const propertyType = getTypeOfSymbol(propertySymbol);
const propertyType = getCheckFlags(propertySymbol) & CheckFlags.ReverseMapped ? anyType : getTypeOfSymbol(propertySymbol);
const saveEnclosingDeclaration = context.enclosingDeclaration;
context.enclosingDeclaration = undefined;
const propertyName = symbolToName(propertySymbol, context, SymbolFlags.Value, /*expectsIdentifier*/ true);
@@ -3681,7 +3685,10 @@ namespace ts {
writePunctuation(writer, SyntaxKind.SemicolonToken);
writer.writeLine();
}
buildIndexSignatureDisplay(resolved.stringIndexInfo, writer, IndexKind.String, enclosingDeclaration, globalFlags, symbolStack);
const stringIndexInfo = resolved.objectFlags & ObjectFlags.ReverseMapped && resolved.stringIndexInfo ?
createIndexInfo(anyType, resolved.stringIndexInfo.isReadonly, resolved.stringIndexInfo.declaration) :
resolved.stringIndexInfo;
buildIndexSignatureDisplay(stringIndexInfo, writer, IndexKind.String, enclosingDeclaration, globalFlags, symbolStack);
buildIndexSignatureDisplay(resolved.numberIndexInfo, writer, IndexKind.Number, enclosingDeclaration, globalFlags, symbolStack);
for (const p of resolved.properties) {
if (globalFlags & TypeFormatFlags.WriteClassExpressionAsTypeLiteral) {
@@ -3692,7 +3699,7 @@ namespace ts {
writer.reportPrivateInBaseOfClassExpression(symbolName(p));
}
}
const t = getTypeOfSymbol(p);
const t = getCheckFlags(p) & CheckFlags.ReverseMapped ? anyType : getTypeOfSymbol(p);
if (p.flags & (SymbolFlags.Function | SymbolFlags.Method) && !getPropertiesOfObjectType(t).length) {
const signatures = getSignaturesOfType(t, SignatureKind.Call);
for (const signature of signatures) {
@@ -4900,6 +4907,9 @@ namespace ts {
if (getCheckFlags(symbol) & CheckFlags.Instantiated) {
return getTypeOfInstantiatedSymbol(symbol);
}
if (getCheckFlags(symbol) & CheckFlags.ReverseMapped) {
return getTypeOfReverseMappedSymbol(symbol as ReverseMappedSymbol);
}
if (symbol.flags & (SymbolFlags.Variable | SymbolFlags.Property)) {
return getTypeOfVariableOrParameterOrProperty(symbol);
}
@@ -6110,6 +6120,23 @@ namespace ts {
}
}
function resolveReverseMappedTypeMembers(type: ReverseMappedType) {
const indexInfo = getIndexInfoOfType(type.source, IndexKind.String);
const readonlyMask = type.mappedType.declaration.readonlyToken ? false : true;
const optionalMask = type.mappedType.declaration.questionToken ? 0 : SymbolFlags.Optional;
const stringIndexInfo = indexInfo && createIndexInfo(inferReverseMappedType(indexInfo.type, type.mappedType), readonlyMask && indexInfo.isReadonly);
const members = createSymbolTable();
for (const prop of getPropertiesOfType(type.source)) {
const checkFlags = CheckFlags.ReverseMapped | (readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0);
const inferredProp = createSymbol(SymbolFlags.Property | prop.flags & optionalMask, prop.escapedName, checkFlags) as ReverseMappedSymbol;
inferredProp.declarations = prop.declarations;
inferredProp.propertyType = getTypeOfSymbol(prop);
inferredProp.mappedType = type.mappedType;
members.set(prop.escapedName, inferredProp);
}
setStructuredTypeMembers(type, members, emptyArray, emptyArray, stringIndexInfo, undefined);
}
/** Resolve the members of a mapped type { [P in K]: T } */
function resolveMappedTypeMembers(type: MappedType) {
const members: SymbolTable = createSymbolTable();
@@ -6249,6 +6276,9 @@ namespace ts {
else if ((<ObjectType>type).objectFlags & ObjectFlags.ClassOrInterface) {
resolveClassOrInterfaceMembers(<InterfaceType>type);
}
else if ((<ReverseMappedType>type).objectFlags & ObjectFlags.ReverseMapped) {
resolveReverseMappedTypeMembers(type as ReverseMappedType);
}
else if ((<ObjectType>type).objectFlags & ObjectFlags.Anonymous) {
resolveAnonymousTypeMembers(<AnonymousType>type);
}
@@ -11275,42 +11305,45 @@ namespace ts {
* property is computed by inferring from the source property type to X for the type
* variable T[P] (i.e. we treat the type T[P] as the type variable we're inferring for).
*/
function inferTypeForHomomorphicMappedType(source: Type, target: MappedType, mappedTypeStack: string[]): Type {
function inferTypeForHomomorphicMappedType(source: Type, target: MappedType): Type {
const key = source.id + "," + target.id;
if (reverseMappedCache.has(key)) {
return reverseMappedCache.get(key);
}
reverseMappedCache.set(key, undefined);
const type = createReverseMappedType(source, target);
reverseMappedCache.set(key, type);
return type;
}
function createReverseMappedType(source: Type, target: MappedType) {
const properties = getPropertiesOfType(source);
let indexInfo = getIndexInfoOfType(source, IndexKind.String);
if (properties.length === 0 && !indexInfo) {
if (properties.length === 0 && !getIndexInfoOfType(source, IndexKind.String)) {
return undefined;
}
const typeParameter = <TypeParameter>getIndexedAccessType((<IndexType>getConstraintTypeFromMappedType(target)).type, getTypeParameterFromMappedType(target));
const inference = createInferenceInfo(typeParameter);
const inferences = [inference];
const templateType = getTemplateTypeFromMappedType(target);
const readonlyMask = target.declaration.readonlyToken ? false : true;
const optionalMask = target.declaration.questionToken ? 0 : SymbolFlags.Optional;
const members = createSymbolTable();
// If any property contains context sensitive functions that have been skipped, the source type
// is incomplete and we can't infer a meaningful input type.
for (const prop of properties) {
const propType = getTypeOfSymbol(prop);
// If any property contains context sensitive functions that have been skipped, the source type
// is incomplete and we can't infer a meaningful input type.
if (propType.flags & TypeFlags.ContainsAnyFunctionType) {
if (getTypeOfSymbol(prop).flags & TypeFlags.ContainsAnyFunctionType) {
return undefined;
}
const checkFlags = readonlyMask && isReadonlySymbol(prop) ? CheckFlags.Readonly : 0;
const inferredProp = createSymbol(SymbolFlags.Property | prop.flags & optionalMask, prop.escapedName, checkFlags);
inferredProp.declarations = prop.declarations;
inferredProp.type = inferTargetType(propType);
members.set(prop.escapedName, inferredProp);
}
if (indexInfo) {
indexInfo = createIndexInfo(inferTargetType(indexInfo.type), readonlyMask && indexInfo.isReadonly);
}
return createAnonymousType(undefined, members, emptyArray, emptyArray, indexInfo, undefined);
const reversed = createObjectType(ObjectFlags.ReverseMapped | ObjectFlags.Anonymous, /*symbol*/ undefined) as ReverseMappedType;
reversed.source = source;
reversed.mappedType = target;
return reversed;
}
function inferTargetType(sourceType: Type): Type {
inference.candidates = undefined;
inferTypes(inferences, sourceType, templateType, 0, mappedTypeStack);
return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) : emptyObjectType;
}
function getTypeOfReverseMappedSymbol(symbol: ReverseMappedSymbol) {
return inferReverseMappedType(symbol.propertyType, symbol.mappedType);
}
function inferReverseMappedType(sourceType: Type, target: MappedType): Type {
const typeParameter = <TypeParameter>getIndexedAccessType((<IndexType>getConstraintTypeFromMappedType(target)).type, getTypeParameterFromMappedType(target));
const templateType = getTemplateTypeFromMappedType(target);
const inference = createInferenceInfo(typeParameter);
inferTypes([inference], sourceType, templateType);
return inference.candidates ? getUnionType(inference.candidates, UnionReduction.Subtype) : emptyObjectType;
}
function getUnmatchedProperty(source: Type, target: Type, requireOptionalProperties: boolean) {
@@ -11326,7 +11359,7 @@ namespace ts {
return undefined;
}
function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0, mappedTypeStack?: string[]) {
function inferTypes(inferences: InferenceInfo[], originalSource: Type, originalTarget: Type, priority: InferencePriority = 0) {
let symbolStack: Symbol[];
let visited: Map<boolean>;
inferFromTypes(originalSource, originalTarget);
@@ -11543,13 +11576,7 @@ namespace ts {
// such that direct inferences to T get priority over inferences to Partial<T>, for example.
const inference = getInferenceInfoForType((<IndexType>constraintType).type);
if (inference && !inference.isFixed) {
const key = (source.symbol ? getSymbolId(source.symbol) + "," : "") + getSymbolId(target.symbol);
if (contains(mappedTypeStack, key)) {
return;
}
(mappedTypeStack || (mappedTypeStack = [])).push(key);
const inferredType = inferTypeForHomomorphicMappedType(source, <MappedType>target, mappedTypeStack);
mappedTypeStack.pop();
const inferredType = inferTypeForHomomorphicMappedType(source, <MappedType>target);
if (inferredType) {
const savePriority = priority;
priority |= InferencePriority.MappedType;
+14
View File
@@ -3251,6 +3251,7 @@ namespace ts {
ContainsPrivate = 1 << 8, // Synthetic property with private constituent(s)
ContainsStatic = 1 << 9, // Synthetic property with static constituent(s)
Late = 1 << 10, // Late-bound symbol for a computed property with a dynamic name
ReverseMapped = 1 << 11, // property of reverse-inferred homomorphic mapped type.
Synthetic = SyntheticProperty | SyntheticMethod
}
@@ -3260,6 +3261,12 @@ namespace ts {
isRestParameter?: boolean;
}
/* @internal */
export interface ReverseMappedSymbol extends TransientSymbol {
propertyType: Type;
mappedType: MappedType;
}
export const enum InternalSymbolName {
Call = "__call", // Call signatures
Constructor = "__constructor", // Constructor implementations
@@ -3494,6 +3501,7 @@ namespace ts {
EvolvingArray = 1 << 8, // Evolving array type
ObjectLiteralPatternWithComputedProperties = 1 << 9, // Object literal pattern with computed properties
ContainsSpread = 1 << 10, // Object literal contains spread operation
ReverseMapped = 1 << 11, // Object contains a property from a reverse-mapped type
ClassOrInterface = Class | Interface
}
@@ -3601,6 +3609,12 @@ namespace ts {
finalArrayType?: Type; // Final array type of evolving array type
}
/* @internal */
export interface ReverseMappedType extends ObjectType {
source: Type;
mappedType: MappedType;
}
/* @internal */
// Resolved object, union, or intersection type
export interface ResolvedType extends ObjectType, UnionOrIntersectionType {
+1
View File
@@ -2066,6 +2066,7 @@ declare namespace ts {
EvolvingArray = 256,
ObjectLiteralPatternWithComputedProperties = 512,
ContainsSpread = 1024,
ReverseMapped = 2048,
ClassOrInterface = 3,
}
interface ObjectType extends Type {
+1
View File
@@ -2066,6 +2066,7 @@ declare namespace ts {
EvolvingArray = 256,
ObjectLiteralPatternWithComputedProperties = 512,
ContainsSpread = 1024,
ReverseMapped = 2048,
ClassOrInterface = 3,
}
interface ObjectType extends Type {
@@ -310,17 +310,11 @@ declare type Spec<T> = {
*/
declare function applySpec<T>(obj: Spec<T>): (...args: any[]) => T;
declare var g1: (...args: any[]) => {
sum: number;
nested: {
mul: string;
};
sum: any;
nested: any;
};
declare var g2: (...args: any[]) => {
foo: {
bar: {
baz: boolean;
};
};
foo: any;
};
declare const foo: <T>(object: T, partial: Partial<T>) => T;
declare let o: {
@@ -203,15 +203,15 @@ function f2() {
};
let v = unboxify(b);
>v : { a: number; b: string; c: boolean; }
>unboxify(b) : { a: number; b: string; c: boolean; }
>v : { a: any; b: any; c: any; }
>unboxify(b) : { a: any; b: any; c: any; }
>unboxify : <T>(obj: Boxified<T>) => T
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
let x: number = v.a;
>x : number
>v.a : number
>v : { a: number; b: string; c: boolean; }
>v : { a: any; b: any; c: any; }
>a : number
}
@@ -277,11 +277,11 @@ function f4() {
};
b = boxify(unboxify(b));
>b = boxify(unboxify(b)) : Boxified<{ a: number; b: string; c: boolean; }>
>b = boxify(unboxify(b)) : Boxified<{ a: any; b: any; c: any; }>
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
>boxify(unboxify(b)) : Boxified<{ a: number; b: string; c: boolean; }>
>boxify(unboxify(b)) : Boxified<{ a: any; b: any; c: any; }>
>boxify : <T>(obj: T) => Boxified<T>
>unboxify(b) : { a: number; b: string; c: boolean; }
>unboxify(b) : { a: any; b: any; c: any; }
>unboxify : <T>(obj: Boxified<T>) => T
>b : { a: Box<number>; b: Box<string>; c: Box<boolean>; }
@@ -338,15 +338,15 @@ function f5(s: string) {
});
let v = unboxify(b);
>v : { a: string | number | boolean; b: string | number | boolean; c: string | number | boolean; }
>unboxify(b) : { a: string | number | boolean; b: string | number | boolean; c: string | number | boolean; }
>v : { a: any; b: any; c: any; }
>unboxify(b) : { a: any; b: any; c: any; }
>unboxify : <T>(obj: Boxified<T>) => T
>b : { a: Box<number> | Box<string> | Box<boolean>; b: Box<number> | Box<string> | Box<boolean>; c: Box<number> | Box<string> | Box<boolean>; }
let x: string | number | boolean = v.a;
>x : string | number | boolean
>v.a : string | number | boolean
>v : { a: string | number | boolean; b: string | number | boolean; c: string | number | boolean; }
>v : { a: any; b: any; c: any; }
>a : string | number | boolean
}
@@ -391,15 +391,15 @@ function f6(s: string) {
});
let v = unboxify(b);
>v : { [x: string]: string | number | boolean; }
>unboxify(b) : { [x: string]: string | number | boolean; }
>v : { [x: string]: any; }
>unboxify(b) : { [x: string]: any; }
>unboxify : <T>(obj: Boxified<T>) => T
>b : { [x: string]: Box<number> | Box<string> | Box<boolean>; }
let x: string | number | boolean = v[s];
>x : string | number | boolean
>v[s] : string | number | boolean
>v : { [x: string]: string | number | boolean; }
>v : { [x: string]: any; }
>s : string
}
@@ -449,20 +449,20 @@ function f10(foo: Foo) {
>Foo : Foo
let x = validate(foo); // { a: number, readonly b: string }
>x : { a: number; readonly b: string; }
>validate(foo) : { a: number; readonly b: string; }
>x : { a: any; readonly b: any; }
>validate(foo) : { a: any; readonly b: any; }
>validate : <T>(obj: { [P in keyof T]?: T[P] | undefined; }) => T
>foo : Foo
let y = clone(foo); // { a?: number, b: string }
>y : { a?: number | undefined; b: string; }
>clone(foo) : { a?: number | undefined; b: string; }
>y : { a?: any; b: any; }
>clone(foo) : { a?: any; b: any; }
>clone : <T>(obj: { readonly [P in keyof T]: T[P]; }) => T
>foo : Foo
let z = validateAndClone(foo); // { a: number, b: string }
>z : { a: number; b: string; }
>validateAndClone(foo) : { a: number; b: string; }
>z : { a: any; b: any; }
>validateAndClone(foo) : { a: any; b: any; }
>validateAndClone : <T>(obj: { readonly [P in keyof T]?: T[P] | undefined; }) => T
>foo : Foo
}
@@ -507,8 +507,8 @@ declare function applySpec<T>(obj: Spec<T>): (...args: any[]) => T;
// Infers g1: (...args: any[]) => { sum: number, nested: { mul: string } }
var g1 = applySpec({
>g1 : (...args: any[]) => { sum: number; nested: { mul: string; }; }
>applySpec({ sum: (a: any) => 3, nested: { mul: (b: any) => "n" }}) : (...args: any[]) => { sum: number; nested: { mul: string; }; }
>g1 : (...args: any[]) => { sum: any; nested: any; }
>applySpec({ sum: (a: any) => 3, nested: { mul: (b: any) => "n" }}) : (...args: any[]) => { sum: any; nested: any; }
>applySpec : <T>(obj: Spec<T>) => (...args: any[]) => T
>{ sum: (a: any) => 3, nested: { mul: (b: any) => "n" }} : { sum: (a: any) => number; nested: { mul: (b: any) => string; }; }
@@ -532,8 +532,8 @@ var g1 = applySpec({
// Infers g2: (...args: any[]) => { foo: { bar: { baz: boolean } } }
var g2 = applySpec({ foo: { bar: { baz: (x: any) => true } } });
>g2 : (...args: any[]) => { foo: { bar: { baz: boolean; }; }; }
>applySpec({ foo: { bar: { baz: (x: any) => true } } }) : (...args: any[]) => { foo: { bar: { baz: boolean; }; }; }
>g2 : (...args: any[]) => { foo: any; }
>applySpec({ foo: { bar: { baz: (x: any) => true } } }) : (...args: any[]) => { foo: any; }
>applySpec : <T>(obj: Spec<T>) => (...args: any[]) => T
>{ foo: { bar: { baz: (x: any) => true } } } : { foo: { bar: { baz: (x: any) => boolean; }; }; }
>foo : { bar: { baz: (x: any) => boolean; }; }
@@ -1102,10 +1102,10 @@ declare type Handlers<T> = {
};
declare function on<T>(handlerHash: Handlers<T>): T;
declare var hashOfEmpty1: {
test: {};
test: any;
};
declare var hashOfEmpty2: {
test: boolean;
test: any;
};
interface Options1<Data, Computed> {
data?: Data;
@@ -1793,16 +1793,16 @@ declare function on<T>(handlerHash: Handlers<T>): T
>T : T
var hashOfEmpty1 = on({ test: () => {} }); // {}
>hashOfEmpty1 : { test: {}; }
>on({ test: () => {} }) : { test: {}; }
>hashOfEmpty1 : { test: any; }
>on({ test: () => {} }) : { test: any; }
>on : <T>(handlerHash: Handlers<T>) => T
>{ test: () => {} } : { test: () => void; }
>test : () => void
>() => {} : () => void
var hashOfEmpty2 = on({ test: (x: boolean) => {} }); // { test: boolean }
>hashOfEmpty2 : { test: boolean; }
>on({ test: (x: boolean) => {} }) : { test: boolean; }
>hashOfEmpty2 : { test: any; }
>on({ test: (x: boolean) => {} }) : { test: any; }
>on : <T>(handlerHash: Handlers<T>) => T
>{ test: (x: boolean) => {} } : { test: (x: boolean) => void; }
>test : (x: boolean) => void
@@ -1,7 +1,7 @@
tests/cases/conformance/types/mapped/mappedTypeInferenceErrors.ts(9,5): error TS2345: Argument of type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to parameter of type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: number; baz: {}; }>; } & ThisType<{ x: number; y: number; } & { bar: number; baz: {}; }>'.
Type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: number; baz: {}; }>; }'.
tests/cases/conformance/types/mapped/mappedTypeInferenceErrors.ts(9,5): error TS2345: Argument of type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to parameter of type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: any; baz: any; }>; } & ThisType<{ x: number; y: number; } & { bar: any; baz: any; }>'.
Type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: any; baz: any; }>; }'.
Types of property 'computed' are incompatible.
Type '{ bar(): number; baz: number; }' is not assignable to type 'ComputedOf<{ bar: number; baz: {}; }>'.
Type '{ bar(): number; baz: number; }' is not assignable to type 'ComputedOf<{ bar: any; baz: any; }>'.
Types of property 'baz' are incompatible.
Type 'number' is not assignable to type '() => {}'.
@@ -35,10 +35,10 @@ tests/cases/conformance/types/mapped/mappedTypeInferenceErrors.ts(9,5): error TS
~~~~~
});
~
!!! error TS2345: Argument of type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to parameter of type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: number; baz: {}; }>; } & ThisType<{ x: number; y: number; } & { bar: number; baz: {}; }>'.
!!! error TS2345: Type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: number; baz: {}; }>; }'.
!!! error TS2345: Argument of type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to parameter of type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: any; baz: any; }>; } & ThisType<{ x: number; y: number; } & { bar: any; baz: any; }>'.
!!! error TS2345: Type '{ props: { x: number; y: number; }; computed: { bar(): number; baz: number; }; }' is not assignable to type '{ props: { x: number; y: number; }; computed: ComputedOf<{ bar: any; baz: any; }>; }'.
!!! error TS2345: Types of property 'computed' are incompatible.
!!! error TS2345: Type '{ bar(): number; baz: number; }' is not assignable to type 'ComputedOf<{ bar: number; baz: {}; }>'.
!!! error TS2345: Type '{ bar(): number; baz: number; }' is not assignable to type 'ComputedOf<{ bar: any; baz: any; }>'.
!!! error TS2345: Types of property 'baz' are incompatible.
!!! error TS2345: Type 'number' is not assignable to type '() => {}'.
@@ -4,7 +4,34 @@ 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
//// [mappedTypeRecursiveInference.js]
var out = foo(a);
out.a;
out.a.a;
out.a.a.a.a.a.a.a;
var oub = foo(b);
oub.b;
oub.b.b;
oub.b.a.n.a.n.a;
var xhr;
var out2 = foo(xhr);
out2.responseXML;
out2.responseXML.activeElement.className.length;
@@ -30,3 +30,81 @@ const out = foo(a);
>foo : Symbol(foo, Decl(mappedTypeRecursiveInference.ts, 2, 45))
>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 1, 11))
out.a
>out.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13))
>out : Symbol(out, Decl(mappedTypeRecursiveInference.ts, 4, 5))
>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13))
out.a.a
>out.a.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13))
>out.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13))
>out : Symbol(out, Decl(mappedTypeRecursiveInference.ts, 4, 5))
>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13))
>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13))
out.a.a.a.a.a.a.a
>out.a.a.a.a.a.a.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13))
>out.a.a.a.a.a.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13))
>out.a.a.a.a.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13))
>out.a.a.a.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13))
>out.a.a.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13))
>out.a.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13))
>out.a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13))
>out : Symbol(out, Decl(mappedTypeRecursiveInference.ts, 4, 5))
>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13))
>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13))
>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13))
>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13))
>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13))
>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13))
>a : Symbol(a, Decl(mappedTypeRecursiveInference.ts, 0, 13))
interface B { [s: string]: B }
>B : Symbol(B, Decl(mappedTypeRecursiveInference.ts, 7, 17))
>s : Symbol(s, Decl(mappedTypeRecursiveInference.ts, 10, 15))
>B : Symbol(B, Decl(mappedTypeRecursiveInference.ts, 7, 17))
declare let b: B;
>b : Symbol(b, Decl(mappedTypeRecursiveInference.ts, 11, 11))
>B : Symbol(B, Decl(mappedTypeRecursiveInference.ts, 7, 17))
const oub = foo(b);
>oub : Symbol(oub, Decl(mappedTypeRecursiveInference.ts, 12, 5))
>foo : Symbol(foo, Decl(mappedTypeRecursiveInference.ts, 2, 45))
>b : Symbol(b, Decl(mappedTypeRecursiveInference.ts, 11, 11))
oub.b
>oub : Symbol(oub, Decl(mappedTypeRecursiveInference.ts, 12, 5))
oub.b.b
>oub : Symbol(oub, Decl(mappedTypeRecursiveInference.ts, 12, 5))
oub.b.a.n.a.n.a
>oub : Symbol(oub, Decl(mappedTypeRecursiveInference.ts, 12, 5))
let xhr: XMLHttpRequest;
>xhr : Symbol(xhr, Decl(mappedTypeRecursiveInference.ts, 17, 3))
>XMLHttpRequest : Symbol(XMLHttpRequest, Decl(lib.dom.d.ts, --, --), Decl(lib.dom.d.ts, --, --))
const out2 = foo(xhr);
>out2 : Symbol(out2, Decl(mappedTypeRecursiveInference.ts, 18, 5))
>foo : Symbol(foo, Decl(mappedTypeRecursiveInference.ts, 2, 45))
>xhr : Symbol(xhr, Decl(mappedTypeRecursiveInference.ts, 17, 3))
out2.responseXML
>out2.responseXML : Symbol(responseXML, Decl(lib.dom.d.ts, --, --))
>out2 : Symbol(out2, Decl(mappedTypeRecursiveInference.ts, 18, 5))
>responseXML : Symbol(responseXML, Decl(lib.dom.d.ts, --, --))
out2.responseXML.activeElement.className.length
>out2.responseXML.activeElement.className.length : Symbol(length, Decl(lib.es5.d.ts, --, --))
>out2.responseXML.activeElement.className : Symbol(className, Decl(lib.dom.d.ts, --, --))
>out2.responseXML.activeElement : Symbol(activeElement, Decl(lib.dom.d.ts, --, --))
>out2.responseXML : Symbol(responseXML, Decl(lib.dom.d.ts, --, --))
>out2 : Symbol(out2, Decl(mappedTypeRecursiveInference.ts, 18, 5))
>responseXML : Symbol(responseXML, Decl(lib.dom.d.ts, --, --))
>activeElement : Symbol(activeElement, Decl(lib.dom.d.ts, --, --))
>className : Symbol(className, Decl(lib.dom.d.ts, --, --))
>length : Symbol(length, Decl(lib.es5.d.ts, --, --))
@@ -26,8 +26,106 @@ declare function foo<T>(deep: Deep<T>): T;
>T : T
const out = foo(a);
>out : { a: {}; }
>foo(a) : { a: {}; }
>out : { a: any; }
>foo(a) : { a: any; }
>foo : <T>(deep: Deep<T>) => T
>a : A
out.a
>out.a : { a: any; }
>out : { a: any; }
>a : { a: any; }
out.a.a
>out.a.a : { a: any; }
>out.a : { a: any; }
>out : { a: any; }
>a : { a: any; }
>a : { a: any; }
out.a.a.a.a.a.a.a
>out.a.a.a.a.a.a.a : { a: any; }
>out.a.a.a.a.a.a : { a: any; }
>out.a.a.a.a.a : { a: any; }
>out.a.a.a.a : { a: any; }
>out.a.a.a : { a: any; }
>out.a.a : { a: any; }
>out.a : { a: any; }
>out : { a: any; }
>a : { a: any; }
>a : { a: any; }
>a : { a: any; }
>a : { a: any; }
>a : { a: any; }
>a : { a: any; }
>a : { a: any; }
interface B { [s: string]: B }
>B : B
>s : string
>B : B
declare let b: B;
>b : B
>B : B
const oub = foo(b);
>oub : { [x: string]: any; }
>foo(b) : { [x: string]: any; }
>foo : <T>(deep: Deep<T>) => T
>b : B
oub.b
>oub.b : { [x: string]: any; }
>oub : { [x: string]: any; }
>b : { [x: string]: any; }
oub.b.b
>oub.b.b : { [x: string]: any; }
>oub.b : { [x: string]: any; }
>oub : { [x: string]: any; }
>b : { [x: string]: any; }
>b : { [x: string]: any; }
oub.b.a.n.a.n.a
>oub.b.a.n.a.n.a : { [x: string]: any; }
>oub.b.a.n.a.n : { [x: string]: any; }
>oub.b.a.n.a : { [x: string]: any; }
>oub.b.a.n : { [x: string]: any; }
>oub.b.a : { [x: string]: any; }
>oub.b : { [x: string]: any; }
>oub : { [x: string]: any; }
>b : { [x: string]: any; }
>a : { [x: string]: any; }
>n : { [x: string]: any; }
>a : { [x: string]: any; }
>n : { [x: string]: any; }
>a : { [x: string]: any; }
let xhr: XMLHttpRequest;
>xhr : XMLHttpRequest
>XMLHttpRequest : XMLHttpRequest
const out2 = foo(xhr);
>out2 : { onreadystatechange: any; readonly readyState: any; readonly response: any; readonly responseText: any; responseType: any; readonly responseURL: any; readonly responseXML: any; readonly status: any; readonly statusText: any; timeout: any; readonly upload: any; withCredentials: any; msCaching?: any; abort: any; getAllResponseHeaders: any; getResponseHeader: any; msCachingEnabled: any; open: any; overrideMimeType: any; send: any; setRequestHeader: any; readonly DONE: any; readonly HEADERS_RECEIVED: any; readonly LOADING: any; readonly OPENED: any; readonly UNSENT: any; addEventListener: any; removeEventListener: any; dispatchEvent: any; onabort: any; onerror: any; onload: any; onloadend: any; onloadstart: any; onprogress: any; ontimeout: any; }
>foo(xhr) : { onreadystatechange: any; readonly readyState: any; readonly response: any; readonly responseText: any; responseType: any; readonly responseURL: any; readonly responseXML: any; readonly status: any; readonly statusText: any; timeout: any; readonly upload: any; withCredentials: any; msCaching?: any; abort: any; getAllResponseHeaders: any; getResponseHeader: any; msCachingEnabled: any; open: any; overrideMimeType: any; send: any; setRequestHeader: any; readonly DONE: any; readonly HEADERS_RECEIVED: any; readonly LOADING: any; readonly OPENED: any; readonly UNSENT: any; addEventListener: any; removeEventListener: any; dispatchEvent: any; onabort: any; onerror: any; onload: any; onloadend: any; onloadstart: any; onprogress: any; ontimeout: any; }
>foo : <T>(deep: Deep<T>) => T
>xhr : XMLHttpRequest
out2.responseXML
>out2.responseXML : { readonly activeElement: any; alinkColor: any; readonly all: any; anchors: any; applets: any; bgColor: any; body: any; readonly characterSet: any; charset: any; readonly compatMode: any; cookie: any; readonly currentScript: any; readonly defaultView: any; designMode: any; dir: any; readonly doctype: any; documentElement: any; domain: any; embeds: any; fgColor: any; forms: any; readonly fullscreenElement: any; readonly fullscreenEnabled: any; readonly head: any; readonly hidden: any; images: any; readonly implementation: any; readonly inputEncoding: any; readonly lastModified: any; linkColor: any; links: any; readonly location: any; msCapsLockWarningOff: any; msCSSOMElementFloatMetrics: any; onabort: any; onactivate: any; onbeforeactivate: any; onbeforedeactivate: any; onblur: any; oncanplay: any; oncanplaythrough: any; onchange: any; onclick: any; oncontextmenu: any; ondblclick: any; ondeactivate: any; ondrag: any; ondragend: any; ondragenter: any; ondragleave: any; ondragover: any; ondragstart: any; ondrop: any; ondurationchange: any; onemptied: any; onended: any; onerror: any; onfocus: any; onfullscreenchange: any; onfullscreenerror: any; oninput: any; oninvalid: any; onkeydown: any; onkeypress: any; onkeyup: any; onload: any; onloadeddata: any; onloadedmetadata: any; onloadstart: any; onmousedown: any; onmousemove: any; onmouseout: any; onmouseover: any; onmouseup: any; onmousewheel: any; onmscontentzoom: any; onmsgesturechange: any; onmsgesturedoubletap: any; onmsgestureend: any; onmsgesturehold: any; onmsgesturestart: any; onmsgesturetap: any; onmsinertiastart: any; onmsmanipulationstatechanged: any; onmspointercancel: any; onmspointerdown: any; onmspointerenter: any; onmspointerleave: any; onmspointermove: any; onmspointerout: any; onmspointerover: any; onmspointerup: any; onmssitemodejumplistitemremoved: any; onmsthumbnailclick: any; onpause: any; onplay: any; onplaying: any; onpointerlockchange: any; onpointerlockerror: any; onprogress: any; onratechange: any; onreadystatechange: any; onreset: any; onscroll: any; onseeked: any; onseeking: any; onselect: any; onselectionchange: any; onselectstart: any; onstalled: any; onstop: any; onsubmit: any; onsuspend: any; ontimeupdate: any; ontouchcancel: any; ontouchend: any; ontouchmove: any; ontouchstart: any; onvolumechange: any; onwaiting: any; onwebkitfullscreenchange: any; onwebkitfullscreenerror: any; plugins: any; readonly pointerLockElement: any; readonly readyState: any; readonly referrer: any; readonly rootElement: any; scripts: any; readonly scrollingElement: any; readonly styleSheets: any; title: any; readonly URL: any; readonly URLUnencoded: any; readonly visibilityState: any; vlinkColor: any; readonly webkitCurrentFullScreenElement: any; readonly webkitFullscreenElement: any; readonly webkitFullscreenEnabled: any; readonly webkitIsFullScreen: any; readonly xmlEncoding: any; xmlStandalone: any; xmlVersion: any; adoptNode: any; captureEvents: any; caretRangeFromPoint: any; clear: any; close: any; createAttribute: any; createAttributeNS: any; createCDATASection: any; createComment: any; createDocumentFragment: any; createElement: any; createElementNS: any; createExpression: any; createNodeIterator: any; createNSResolver: any; createProcessingInstruction: any; createRange: any; createTextNode: any; createTouch: any; createTouchList: any; createTreeWalker: any; elementFromPoint: any; evaluate: any; execCommand: any; execCommandShowHelp: any; exitFullscreen: any; exitPointerLock: any; focus: any; getElementById: any; getElementsByClassName: any; getElementsByName: any; getElementsByTagName: any; getElementsByTagNameNS: any; getSelection: any; hasFocus: any; importNode: any; msElementsFromPoint: any; msElementsFromRect: any; open: any; queryCommandEnabled: any; queryCommandIndeterm: any; queryCommandState: any; queryCommandSupported: any; queryCommandText: any; queryCommandValue: any; releaseEvents: any; updateSettings: any; webkitCancelFullScreen: any; webkitExitFullscreen: any; write: any; writeln: any; addEventListener: any; removeEventListener: any; readonly attributes: any; readonly baseURI: any; readonly childNodes: any; readonly firstChild: any; readonly lastChild: any; readonly localName: any; readonly namespaceURI: any; readonly nextSibling: any; readonly nodeName: any; readonly nodeType: any; nodeValue: any; readonly ownerDocument: any; readonly parentElement: any; readonly parentNode: any; readonly previousSibling: any; textContent: any; appendChild: any; cloneNode: any; compareDocumentPosition: any; contains: any; hasAttributes: any; hasChildNodes: any; insertBefore: any; isDefaultNamespace: any; isEqualNode: any; isSameNode: any; lookupNamespaceURI: any; lookupPrefix: any; normalize: any; removeChild: any; replaceChild: any; readonly ATTRIBUTE_NODE: any; readonly CDATA_SECTION_NODE: any; readonly COMMENT_NODE: any; readonly DOCUMENT_FRAGMENT_NODE: any; readonly DOCUMENT_NODE: any; readonly DOCUMENT_POSITION_CONTAINED_Line truncated
>out2 : { onreadystatechange: any; readonly readyState: any; readonly response: any; readonly responseText: any; responseType: any; readonly responseURL: any; readonly responseXML: any; readonly status: any; readonly statusText: any; timeout: any; readonly upload: any; withCredentials: any; msCaching?: any; abort: any; getAllResponseHeaders: any; getResponseHeader: any; msCachingEnabled: any; open: any; overrideMimeType: any; send: any; setRequestHeader: any; readonly DONE: any; readonly HEADERS_RECEIVED: any; readonly LOADING: any; readonly OPENED: any; readonly UNSENT: any; addEventListener: any; removeEventListener: any; dispatchEvent: any; onabort: any; onerror: any; onload: any; onloadend: any; onloadstart: any; onprogress: any; ontimeout: any; }
>responseXML : { readonly activeElement: any; alinkColor: any; readonly all: any; anchors: any; applets: any; bgColor: any; body: any; readonly characterSet: any; charset: any; readonly compatMode: any; cookie: any; readonly currentScript: any; readonly defaultView: any; designMode: any; dir: any; readonly doctype: any; documentElement: any; domain: any; embeds: any; fgColor: any; forms: any; readonly fullscreenElement: any; readonly fullscreenEnabled: any; readonly head: any; readonly hidden: any; images: any; readonly implementation: any; readonly inputEncoding: any; readonly lastModified: any; linkColor: any; links: any; readonly location: any; msCapsLockWarningOff: any; msCSSOMElementFloatMetrics: any; onabort: any; onactivate: any; onbeforeactivate: any; onbeforedeactivate: any; onblur: any; oncanplay: any; oncanplaythrough: any; onchange: any; onclick: any; oncontextmenu: any; ondblclick: any; ondeactivate: any; ondrag: any; ondragend: any; ondragenter: any; ondragleave: any; ondragover: any; ondragstart: any; ondrop: any; ondurationchange: any; onemptied: any; onended: any; onerror: any; onfocus: any; onfullscreenchange: any; onfullscreenerror: any; oninput: any; oninvalid: any; onkeydown: any; onkeypress: any; onkeyup: any; onload: any; onloadeddata: any; onloadedmetadata: any; onloadstart: any; onmousedown: any; onmousemove: any; onmouseout: any; onmouseover: any; onmouseup: any; onmousewheel: any; onmscontentzoom: any; onmsgesturechange: any; onmsgesturedoubletap: any; onmsgestureend: any; onmsgesturehold: any; onmsgesturestart: any; onmsgesturetap: any; onmsinertiastart: any; onmsmanipulationstatechanged: any; onmspointercancel: any; onmspointerdown: any; onmspointerenter: any; onmspointerleave: any; onmspointermove: any; onmspointerout: any; onmspointerover: any; onmspointerup: any; onmssitemodejumplistitemremoved: any; onmsthumbnailclick: any; onpause: any; onplay: any; onplaying: any; onpointerlockchange: any; onpointerlockerror: any; onprogress: any; onratechange: any; onreadystatechange: any; onreset: any; onscroll: any; onseeked: any; onseeking: any; onselect: any; onselectionchange: any; onselectstart: any; onstalled: any; onstop: any; onsubmit: any; onsuspend: any; ontimeupdate: any; ontouchcancel: any; ontouchend: any; ontouchmove: any; ontouchstart: any; onvolumechange: any; onwaiting: any; onwebkitfullscreenchange: any; onwebkitfullscreenerror: any; plugins: any; readonly pointerLockElement: any; readonly readyState: any; readonly referrer: any; readonly rootElement: any; scripts: any; readonly scrollingElement: any; readonly styleSheets: any; title: any; readonly URL: any; readonly URLUnencoded: any; readonly visibilityState: any; vlinkColor: any; readonly webkitCurrentFullScreenElement: any; readonly webkitFullscreenElement: any; readonly webkitFullscreenEnabled: any; readonly webkitIsFullScreen: any; readonly xmlEncoding: any; xmlStandalone: any; xmlVersion: any; adoptNode: any; captureEvents: any; caretRangeFromPoint: any; clear: any; close: any; createAttribute: any; createAttributeNS: any; createCDATASection: any; createComment: any; createDocumentFragment: any; createElement: any; createElementNS: any; createExpression: any; createNodeIterator: any; createNSResolver: any; createProcessingInstruction: any; createRange: any; createTextNode: any; createTouch: any; createTouchList: any; createTreeWalker: any; elementFromPoint: any; evaluate: any; execCommand: any; execCommandShowHelp: any; exitFullscreen: any; exitPointerLock: any; focus: any; getElementById: any; getElementsByClassName: any; getElementsByName: any; getElementsByTagName: any; getElementsByTagNameNS: any; getSelection: any; hasFocus: any; importNode: any; msElementsFromPoint: any; msElementsFromRect: any; open: any; queryCommandEnabled: any; queryCommandIndeterm: any; queryCommandState: any; queryCommandSupported: any; queryCommandText: any; queryCommandValue: any; releaseEvents: any; updateSettings: any; webkitCancelFullScreen: any; webkitExitFullscreen: any; write: any; writeln: any; addEventListener: any; removeEventListener: any; readonly attributes: any; readonly baseURI: any; readonly childNodes: any; readonly firstChild: any; readonly lastChild: any; readonly localName: any; readonly namespaceURI: any; readonly nextSibling: any; readonly nodeName: any; readonly nodeType: any; nodeValue: any; readonly ownerDocument: any; readonly parentElement: any; readonly parentNode: any; readonly previousSibling: any; textContent: any; appendChild: any; cloneNode: any; compareDocumentPosition: any; contains: any; hasAttributes: any; hasChildNodes: any; insertBefore: any; isDefaultNamespace: any; isEqualNode: any; isSameNode: any; lookupNamespaceURI: any; lookupPrefix: any; normalize: any; removeChild: any; replaceChild: any; readonly ATTRIBUTE_NODE: any; readonly CDATA_SECTION_NODE: any; readonly COMMENT_NODE: any; readonly DOCUMENT_FRAGMENT_NODE: any; readonly DOCUMENT_NODE: any; readonly DOCUMENT_POSITION_CONTAINED_BY: aLine truncated
out2.responseXML.activeElement.className.length
>out2.responseXML.activeElement.className.length : { toString: any; toFixed: any; toExponential: any; toPrecision: any; valueOf: any; toLocaleString: any; }
>out2.responseXML.activeElement.className : { toString: any; charAt: any; charCodeAt: any; concat: any; indexOf: any; lastIndexOf: any; localeCompare: any; match: any; replace: any; search: any; slice: any; split: any; substring: any; toLowerCase: any; toLocaleLowerCase: any; toUpperCase: any; toLocaleUpperCase: any; trim: any; readonly length: any; substr: any; valueOf: any; [Symbol.iterator]: any; codePointAt: any; includes: any; endsWith: any; normalize: any; repeat: any; startsWith: any; anchor: any; big: any; blink: any; bold: any; fixed: any; fontcolor: any; fontsize: any; italics: any; link: any; small: any; strike: any; sub: any; sup: any; }
>out2.responseXML.activeElement : { readonly classList: any; className: any; readonly clientHeight: any; readonly clientLeft: any; readonly clientTop: any; readonly clientWidth: any; id: any; innerHTML: any; msContentZoomFactor: any; readonly msRegionOverflow: any; onariarequest: any; oncommand: any; ongotpointercapture: any; onlostpointercapture: any; onmsgesturechange: any; onmsgesturedoubletap: any; onmsgestureend: any; onmsgesturehold: any; onmsgesturestart: any; onmsgesturetap: any; onmsgotpointercapture: any; onmsinertiastart: any; onmslostpointercapture: any; onmspointercancel: any; onmspointerdown: any; onmspointerenter: any; onmspointerleave: any; onmspointermove: any; onmspointerout: any; onmspointerover: any; onmspointerup: any; ontouchcancel: any; ontouchend: any; ontouchmove: any; ontouchstart: any; onwebkitfullscreenchange: any; onwebkitfullscreenerror: any; outerHTML: any; readonly prefix: any; readonly scrollHeight: any; scrollLeft: any; scrollTop: any; readonly scrollWidth: any; readonly tagName: any; readonly assignedSlot: any; slot: any; readonly shadowRoot: any; getAttribute: any; getAttributeNode: any; getAttributeNodeNS: any; getAttributeNS: any; getBoundingClientRect: any; getClientRects: any; getElementsByTagName: any; getElementsByTagNameNS: any; hasAttribute: any; hasAttributeNS: any; msGetRegionContent: any; msGetUntransformedBounds: any; msMatchesSelector: any; msReleasePointerCapture: any; msSetPointerCapture: any; msZoomTo: any; releasePointerCapture: any; removeAttribute: any; removeAttributeNode: any; removeAttributeNS: any; requestFullscreen: any; requestPointerLock: any; setAttribute: any; setAttributeNode: any; setAttributeNodeNS: any; setAttributeNS: any; setPointerCapture: any; webkitMatchesSelector: any; webkitRequestFullscreen: any; webkitRequestFullScreen: any; getElementsByClassName: any; matches: any; closest: any; scrollIntoView: any; scroll: any; scrollTo: any; scrollBy: any; insertAdjacentElement: any; insertAdjacentHTML: any; insertAdjacentText: any; attachShadow: any; addEventListener: any; removeEventListener: any; readonly attributes: any; readonly baseURI: any; readonly childNodes: any; readonly firstChild: any; readonly lastChild: any; readonly localName: any; readonly namespaceURI: any; readonly nextSibling: any; readonly nodeName: any; readonly nodeType: any; nodeValue: any; readonly ownerDocument: any; readonly parentElement: any; readonly parentNode: any; readonly previousSibling: any; textContent: any; appendChild: any; cloneNode: any; compareDocumentPosition: any; contains: any; hasAttributes: any; hasChildNodes: any; insertBefore: any; isDefaultNamespace: any; isEqualNode: any; isSameNode: any; lookupNamespaceURI: any; lookupPrefix: any; normalize: any; removeChild: any; replaceChild: any; readonly ATTRIBUTE_NODE: any; readonly CDATA_SECTION_NODE: any; readonly COMMENT_NODE: any; readonly DOCUMENT_FRAGMENT_NODE: any; readonly DOCUMENT_NODE: any; readonly DOCUMENT_POSITION_CONTAINED_BY: any; readonly DOCUMENT_POSITION_CONTAINS: any; readonly DOCUMENT_POSITION_DISCONNECTED: any; readonly DOCUMENT_POSITION_FOLLOWING: any; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: any; readonly DOCUMENT_POSITION_PRECEDING: any; readonly DOCUMENT_TYPE_NODE: any; readonly ELEMENT_NODE: any; readonly ENTITY_NODE: any; readonly ENTITY_REFERENCE_NODE: any; readonly NOTATION_NODE: any; readonly PROCESSING_INSTRUCTION_NODE: any; readonly TEXT_NODE: any; dispatchEvent: any; onpointercancel: any; onpointerdown: any; onpointerenter: any; onpointerleave: any; onpointermove: any; onpointerout: any; onpointerover: any; onpointerup: any; onwheel: any; readonly childElementCount: any; readonly firstElementChild: any; readonly lastElementChild: any; readonly nextElementSibling: any; readonly previousElementSibling: any; querySelector: any; querySelectorAll: any; remove: any; readonly children: any; }
>out2.responseXML : { readonly activeElement: any; alinkColor: any; readonly all: any; anchors: any; applets: any; bgColor: any; body: any; readonly characterSet: any; charset: any; readonly compatMode: any; cookie: any; readonly currentScript: any; readonly defaultView: any; designMode: any; dir: any; readonly doctype: any; documentElement: any; domain: any; embeds: any; fgColor: any; forms: any; readonly fullscreenElement: any; readonly fullscreenEnabled: any; readonly head: any; readonly hidden: any; images: any; readonly implementation: any; readonly inputEncoding: any; readonly lastModified: any; linkColor: any; links: any; readonly location: any; msCapsLockWarningOff: any; msCSSOMElementFloatMetrics: any; onabort: any; onactivate: any; onbeforeactivate: any; onbeforedeactivate: any; onblur: any; oncanplay: any; oncanplaythrough: any; onchange: any; onclick: any; oncontextmenu: any; ondblclick: any; ondeactivate: any; ondrag: any; ondragend: any; ondragenter: any; ondragleave: any; ondragover: any; ondragstart: any; ondrop: any; ondurationchange: any; onemptied: any; onended: any; onerror: any; onfocus: any; onfullscreenchange: any; onfullscreenerror: any; oninput: any; oninvalid: any; onkeydown: any; onkeypress: any; onkeyup: any; onload: any; onloadeddata: any; onloadedmetadata: any; onloadstart: any; onmousedown: any; onmousemove: any; onmouseout: any; onmouseover: any; onmouseup: any; onmousewheel: any; onmscontentzoom: any; onmsgesturechange: any; onmsgesturedoubletap: any; onmsgestureend: any; onmsgesturehold: any; onmsgesturestart: any; onmsgesturetap: any; onmsinertiastart: any; onmsmanipulationstatechanged: any; onmspointercancel: any; onmspointerdown: any; onmspointerenter: any; onmspointerleave: any; onmspointermove: any; onmspointerout: any; onmspointerover: any; onmspointerup: any; onmssitemodejumplistitemremoved: any; onmsthumbnailclick: any; onpause: any; onplay: any; onplaying: any; onpointerlockchange: any; onpointerlockerror: any; onprogress: any; onratechange: any; onreadystatechange: any; onreset: any; onscroll: any; onseeked: any; onseeking: any; onselect: any; onselectionchange: any; onselectstart: any; onstalled: any; onstop: any; onsubmit: any; onsuspend: any; ontimeupdate: any; ontouchcancel: any; ontouchend: any; ontouchmove: any; ontouchstart: any; onvolumechange: any; onwaiting: any; onwebkitfullscreenchange: any; onwebkitfullscreenerror: any; plugins: any; readonly pointerLockElement: any; readonly readyState: any; readonly referrer: any; readonly rootElement: any; scripts: any; readonly scrollingElement: any; readonly styleSheets: any; title: any; readonly URL: any; readonly URLUnencoded: any; readonly visibilityState: any; vlinkColor: any; readonly webkitCurrentFullScreenElement: any; readonly webkitFullscreenElement: any; readonly webkitFullscreenEnabled: any; readonly webkitIsFullScreen: any; readonly xmlEncoding: any; xmlStandalone: any; xmlVersion: any; adoptNode: any; captureEvents: any; caretRangeFromPoint: any; clear: any; close: any; createAttribute: any; createAttributeNS: any; createCDATASection: any; createComment: any; createDocumentFragment: any; createElement: any; createElementNS: any; createExpression: any; createNodeIterator: any; createNSResolver: any; createProcessingInstruction: any; createRange: any; createTextNode: any; createTouch: any; createTouchList: any; createTreeWalker: any; elementFromPoint: any; evaluate: any; execCommand: any; execCommandShowHelp: any; exitFullscreen: any; exitPointerLock: any; focus: any; getElementById: any; getElementsByClassName: any; getElementsByName: any; getElementsByTagName: any; getElementsByTagNameNS: any; getSelection: any; hasFocus: any; importNode: any; msElementsFromPoint: any; msElementsFromRect: any; open: any; queryCommandEnabled: any; queryCommandIndeterm: any; queryCommandState: any; queryCommandSupported: any; queryCommandText: any; queryCommandValue: any; releaseEvents: any; updateSettings: any; webkitCancelFullScreen: any; webkitExitFullscreen: any; write: any; writeln: any; addEventListener: any; removeEventListener: any; readonly attributes: any; readonly baseURI: any; readonly childNodes: any; readonly firstChild: any; readonly lastChild: any; readonly localName: any; readonly namespaceURI: any; readonly nextSibling: any; readonly nodeName: any; readonly nodeType: any; nodeValue: any; readonly ownerDocument: any; readonly parentElement: any; readonly parentNode: any; readonly previousSibling: any; textContent: any; appendChild: any; cloneNode: any; compareDocumentPosition: any; contains: any; hasAttributes: any; hasChildNodes: any; insertBefore: any; isDefaultNamespace: any; isEqualNode: any; isSameNode: any; lookupNamespaceURI: any; lookupPrefix: any; normalize: any; removeChild: any; replaceChild: any; readonly ATTRIBUTE_NODE: any; readonly CDATA_SECTION_NODE: any; readonly COMMENT_NODE: any; readonly DOCUMENT_FRAGMENT_NODE: any; readonly DOCUMENT_NODE: any; readonly DOCUMENT_POSITION_CONTAINED_Line truncated
>out2 : { onreadystatechange: any; readonly readyState: any; readonly response: any; readonly responseText: any; responseType: any; readonly responseURL: any; readonly responseXML: any; readonly status: any; readonly statusText: any; timeout: any; readonly upload: any; withCredentials: any; msCaching?: any; abort: any; getAllResponseHeaders: any; getResponseHeader: any; msCachingEnabled: any; open: any; overrideMimeType: any; send: any; setRequestHeader: any; readonly DONE: any; readonly HEADERS_RECEIVED: any; readonly LOADING: any; readonly OPENED: any; readonly UNSENT: any; addEventListener: any; removeEventListener: any; dispatchEvent: any; onabort: any; onerror: any; onload: any; onloadend: any; onloadstart: any; onprogress: any; ontimeout: any; }
>responseXML : { readonly activeElement: any; alinkColor: any; readonly all: any; anchors: any; applets: any; bgColor: any; body: any; readonly characterSet: any; charset: any; readonly compatMode: any; cookie: any; readonly currentScript: any; readonly defaultView: any; designMode: any; dir: any; readonly doctype: any; documentElement: any; domain: any; embeds: any; fgColor: any; forms: any; readonly fullscreenElement: any; readonly fullscreenEnabled: any; readonly head: any; readonly hidden: any; images: any; readonly implementation: any; readonly inputEncoding: any; readonly lastModified: any; linkColor: any; links: any; readonly location: any; msCapsLockWarningOff: any; msCSSOMElementFloatMetrics: any; onabort: any; onactivate: any; onbeforeactivate: any; onbeforedeactivate: any; onblur: any; oncanplay: any; oncanplaythrough: any; onchange: any; onclick: any; oncontextmenu: any; ondblclick: any; ondeactivate: any; ondrag: any; ondragend: any; ondragenter: any; ondragleave: any; ondragover: any; ondragstart: any; ondrop: any; ondurationchange: any; onemptied: any; onended: any; onerror: any; onfocus: any; onfullscreenchange: any; onfullscreenerror: any; oninput: any; oninvalid: any; onkeydown: any; onkeypress: any; onkeyup: any; onload: any; onloadeddata: any; onloadedmetadata: any; onloadstart: any; onmousedown: any; onmousemove: any; onmouseout: any; onmouseover: any; onmouseup: any; onmousewheel: any; onmscontentzoom: any; onmsgesturechange: any; onmsgesturedoubletap: any; onmsgestureend: any; onmsgesturehold: any; onmsgesturestart: any; onmsgesturetap: any; onmsinertiastart: any; onmsmanipulationstatechanged: any; onmspointercancel: any; onmspointerdown: any; onmspointerenter: any; onmspointerleave: any; onmspointermove: any; onmspointerout: any; onmspointerover: any; onmspointerup: any; onmssitemodejumplistitemremoved: any; onmsthumbnailclick: any; onpause: any; onplay: any; onplaying: any; onpointerlockchange: any; onpointerlockerror: any; onprogress: any; onratechange: any; onreadystatechange: any; onreset: any; onscroll: any; onseeked: any; onseeking: any; onselect: any; onselectionchange: any; onselectstart: any; onstalled: any; onstop: any; onsubmit: any; onsuspend: any; ontimeupdate: any; ontouchcancel: any; ontouchend: any; ontouchmove: any; ontouchstart: any; onvolumechange: any; onwaiting: any; onwebkitfullscreenchange: any; onwebkitfullscreenerror: any; plugins: any; readonly pointerLockElement: any; readonly readyState: any; readonly referrer: any; readonly rootElement: any; scripts: any; readonly scrollingElement: any; readonly styleSheets: any; title: any; readonly URL: any; readonly URLUnencoded: any; readonly visibilityState: any; vlinkColor: any; readonly webkitCurrentFullScreenElement: any; readonly webkitFullscreenElement: any; readonly webkitFullscreenEnabled: any; readonly webkitIsFullScreen: any; readonly xmlEncoding: any; xmlStandalone: any; xmlVersion: any; adoptNode: any; captureEvents: any; caretRangeFromPoint: any; clear: any; close: any; createAttribute: any; createAttributeNS: any; createCDATASection: any; createComment: any; createDocumentFragment: any; createElement: any; createElementNS: any; createExpression: any; createNodeIterator: any; createNSResolver: any; createProcessingInstruction: any; createRange: any; createTextNode: any; createTouch: any; createTouchList: any; createTreeWalker: any; elementFromPoint: any; evaluate: any; execCommand: any; execCommandShowHelp: any; exitFullscreen: any; exitPointerLock: any; focus: any; getElementById: any; getElementsByClassName: any; getElementsByName: any; getElementsByTagName: any; getElementsByTagNameNS: any; getSelection: any; hasFocus: any; importNode: any; msElementsFromPoint: any; msElementsFromRect: any; open: any; queryCommandEnabled: any; queryCommandIndeterm: any; queryCommandState: any; queryCommandSupported: any; queryCommandText: any; queryCommandValue: any; releaseEvents: any; updateSettings: any; webkitCancelFullScreen: any; webkitExitFullscreen: any; write: any; writeln: any; addEventListener: any; removeEventListener: any; readonly attributes: any; readonly baseURI: any; readonly childNodes: any; readonly firstChild: any; readonly lastChild: any; readonly localName: any; readonly namespaceURI: any; readonly nextSibling: any; readonly nodeName: any; readonly nodeType: any; nodeValue: any; readonly ownerDocument: any; readonly parentElement: any; readonly parentNode: any; readonly previousSibling: any; textContent: any; appendChild: any; cloneNode: any; compareDocumentPosition: any; contains: any; hasAttributes: any; hasChildNodes: any; insertBefore: any; isDefaultNamespace: any; isEqualNode: any; isSameNode: any; lookupNamespaceURI: any; lookupPrefix: any; normalize: any; removeChild: any; replaceChild: any; readonly ATTRIBUTE_NODE: any; readonly CDATA_SECTION_NODE: any; readonly COMMENT_NODE: any; readonly DOCUMENT_FRAGMENT_NODE: any; readonly DOCUMENT_NODE: any; readonly DOCUMENT_POSITION_CONTAINED_BY: aLine truncated
>activeElement : { readonly classList: any; className: any; readonly clientHeight: any; readonly clientLeft: any; readonly clientTop: any; readonly clientWidth: any; id: any; innerHTML: any; msContentZoomFactor: any; readonly msRegionOverflow: any; onariarequest: any; oncommand: any; ongotpointercapture: any; onlostpointercapture: any; onmsgesturechange: any; onmsgesturedoubletap: any; onmsgestureend: any; onmsgesturehold: any; onmsgesturestart: any; onmsgesturetap: any; onmsgotpointercapture: any; onmsinertiastart: any; onmslostpointercapture: any; onmspointercancel: any; onmspointerdown: any; onmspointerenter: any; onmspointerleave: any; onmspointermove: any; onmspointerout: any; onmspointerover: any; onmspointerup: any; ontouchcancel: any; ontouchend: any; ontouchmove: any; ontouchstart: any; onwebkitfullscreenchange: any; onwebkitfullscreenerror: any; outerHTML: any; readonly prefix: any; readonly scrollHeight: any; scrollLeft: any; scrollTop: any; readonly scrollWidth: any; readonly tagName: any; readonly assignedSlot: any; slot: any; readonly shadowRoot: any; getAttribute: any; getAttributeNode: any; getAttributeNodeNS: any; getAttributeNS: any; getBoundingClientRect: any; getClientRects: any; getElementsByTagName: any; getElementsByTagNameNS: any; hasAttribute: any; hasAttributeNS: any; msGetRegionContent: any; msGetUntransformedBounds: any; msMatchesSelector: any; msReleasePointerCapture: any; msSetPointerCapture: any; msZoomTo: any; releasePointerCapture: any; removeAttribute: any; removeAttributeNode: any; removeAttributeNS: any; requestFullscreen: any; requestPointerLock: any; setAttribute: any; setAttributeNode: any; setAttributeNodeNS: any; setAttributeNS: any; setPointerCapture: any; webkitMatchesSelector: any; webkitRequestFullscreen: any; webkitRequestFullScreen: any; getElementsByClassName: any; matches: any; closest: any; scrollIntoView: any; scroll: any; scrollTo: any; scrollBy: any; insertAdjacentElement: any; insertAdjacentHTML: any; insertAdjacentText: any; attachShadow: any; addEventListener: any; removeEventListener: any; readonly attributes: any; readonly baseURI: any; readonly childNodes: any; readonly firstChild: any; readonly lastChild: any; readonly localName: any; readonly namespaceURI: any; readonly nextSibling: any; readonly nodeName: any; readonly nodeType: any; nodeValue: any; readonly ownerDocument: any; readonly parentElement: any; readonly parentNode: any; readonly previousSibling: any; textContent: any; appendChild: any; cloneNode: any; compareDocumentPosition: any; contains: any; hasAttributes: any; hasChildNodes: any; insertBefore: any; isDefaultNamespace: any; isEqualNode: any; isSameNode: any; lookupNamespaceURI: any; lookupPrefix: any; normalize: any; removeChild: any; replaceChild: any; readonly ATTRIBUTE_NODE: any; readonly CDATA_SECTION_NODE: any; readonly COMMENT_NODE: any; readonly DOCUMENT_FRAGMENT_NODE: any; readonly DOCUMENT_NODE: any; readonly DOCUMENT_POSITION_CONTAINED_BY: any; readonly DOCUMENT_POSITION_CONTAINS: any; readonly DOCUMENT_POSITION_DISCONNECTED: any; readonly DOCUMENT_POSITION_FOLLOWING: any; readonly DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC: any; readonly DOCUMENT_POSITION_PRECEDING: any; readonly DOCUMENT_TYPE_NODE: any; readonly ELEMENT_NODE: any; readonly ENTITY_NODE: any; readonly ENTITY_REFERENCE_NODE: any; readonly NOTATION_NODE: any; readonly PROCESSING_INSTRUCTION_NODE: any; readonly TEXT_NODE: any; dispatchEvent: any; onpointercancel: any; onpointerdown: any; onpointerenter: any; onpointerleave: any; onpointermove: any; onpointerout: any; onpointerover: any; onpointerup: any; onwheel: any; readonly childElementCount: any; readonly firstElementChild: any; readonly lastElementChild: any; readonly nextElementSibling: any; readonly previousElementSibling: any; querySelector: any; querySelectorAll: any; remove: any; readonly children: any; }
>className : { toString: any; charAt: any; charCodeAt: any; concat: any; indexOf: any; lastIndexOf: any; localeCompare: any; match: any; replace: any; search: any; slice: any; split: any; substring: any; toLowerCase: any; toLocaleLowerCase: any; toUpperCase: any; toLocaleUpperCase: any; trim: any; readonly length: any; substr: any; valueOf: any; [Symbol.iterator]: any; codePointAt: any; includes: any; endsWith: any; normalize: any; repeat: any; startsWith: any; anchor: any; big: any; blink: any; bold: any; fixed: any; fontcolor: any; fontsize: any; italics: any; link: any; small: any; strike: any; sub: any; sup: any; }
>length : { toString: any; toFixed: any; toExponential: any; toPrecision: any; valueOf: any; toLocaleString: any; }
@@ -462,8 +462,8 @@ declare function defineProps<T, U>(obj: T, descs: PropDescMap<U> & ThisType<T>):
declare let p10: Point & Record<"foo", number>;
declare let p11: Point & Record<"bar", number>;
declare let p12: Point & {
foo: number;
bar: number;
foo: any;
bar: any;
};
declare type Accessors<T> = {
[K in keyof T]: (() => T[K]) | Computed<T[K]>;
@@ -487,6 +487,6 @@ declare let vue: {
} & {
f(x: string): number;
} & {
test: number;
hello: string;
test: any;
hello: any;
};
@@ -672,8 +672,8 @@ p11.bar = p11.bar + 1;
>1 : 1
let p12 = defineProps(p1, {
>p12 : Point & { foo: number; bar: number; }
>defineProps(p1, { foo: { value: 42 }, bar: { get(): number { return this.x; }, set(value: number) { this.x = value; } }}) : Point & { foo: number; bar: number; }
>p12 : Point & { foo: any; bar: any; }
>defineProps(p1, { foo: { value: 42 }, bar: { get(): number { return this.x; }, set(value: number) { this.x = value; } }}) : Point & { foo: any; bar: any; }
>defineProps : <T, U>(obj: T, descs: PropDescMap<U> & ThisType<T>) => T & U
>p1 : Point
>{ foo: { value: 42 }, bar: { get(): number { return this.x; }, set(value: number) { this.x = value; } }} : { foo: { value: number; }; bar: { get(): number; set(value: number): void; }; }
@@ -716,22 +716,22 @@ let p12 = defineProps(p1, {
p12.foo = p12.foo + 1;
>p12.foo = p12.foo + 1 : number
>p12.foo : number
>p12 : Point & { foo: number; bar: number; }
>p12 : Point & { foo: any; bar: any; }
>foo : number
>p12.foo + 1 : number
>p12.foo : number
>p12 : Point & { foo: number; bar: number; }
>p12 : Point & { foo: any; bar: any; }
>foo : number
>1 : 1
p12.bar = p12.bar + 1;
>p12.bar = p12.bar + 1 : number
>p12.bar : number
>p12 : Point & { foo: number; bar: number; }
>p12 : Point & { foo: any; bar: any; }
>bar : number
>p12.bar + 1 : number
>p12.bar : number
>p12 : Point & { foo: number; bar: number; }
>p12 : Point & { foo: any; bar: any; }
>bar : number
>1 : 1
@@ -808,8 +808,8 @@ declare const Vue: new <D, M, P>(options: VueOptions<D, M, P>) => D & M & P;
>P : P
let vue = new Vue({
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; }
>new Vue({ data: () => ({ x: 1, y: 2 }), methods: { f(x: string) { return this.x; } }, computed: { test(): number { return this.x; }, hello: { get() { return "hi"; }, set(value: string) { } } }}) : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; }
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; }
>new Vue({ data: () => ({ x: 1, y: 2 }), methods: { f(x: string) { return this.x; } }, computed: { test(): number { return this.x; }, hello: { get() { return "hi"; }, set(value: string) { } } }}) : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; }
>Vue : new <D, M, P>(options: VueOptions<D, M, P>) => D & M & P
>{ data: () => ({ x: 1, y: 2 }), methods: { f(x: string) { return this.x; } }, computed: { test(): number { return this.x; }, hello: { get() { return "hi"; }, set(value: string) { } } }} : { data: () => { x: number; y: number; }; methods: { f(x: string): number; }; computed: { test(): number; hello: { get(): string; set(value: string): void; }; }; }
@@ -833,7 +833,7 @@ let vue = new Vue({
return this.x;
>this.x : number
>this : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; }
>this : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; }
>x : number
}
},
@@ -846,7 +846,7 @@ let vue = new Vue({
return this.x;
>this.x : number
>this : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; }
>this : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; }
>x : number
},
@@ -870,27 +870,27 @@ let vue = new Vue({
});
vue;
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; }
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; }
vue.x;
>vue.x : number
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; }
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; }
>x : number
vue.f("abc");
>vue.f("abc") : number
>vue.f : (x: string) => number
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; }
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; }
>f : (x: string) => number
>"abc" : "abc"
vue.test;
>vue.test : number
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; }
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; }
>test : number
vue.hello;
>vue.hello : string
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: number; hello: string; }
>vue : { x: number; y: number; } & { f(x: string): number; } & { test: any; hello: any; }
>hello : 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,17 @@
/// <reference path="fourslash.ts" />
// @Filename: test.ts
//// 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./*1*/a
//// out.a./*2*/a
//// out.a.a./*3*/a
goTo.marker('1');
verify.completionListCount(1);
goTo.marker('2');
verify.completionListCount(1);
goTo.marker('3');
verify.completionListCount(1);
@@ -0,0 +1,56 @@
/// <reference path="fourslash.ts" />
// @Filename: test.ts
//// 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/*1*/ = foo/*2*/(a);
//// out.a/*3*/
//// out.a.a/*4*/
//// out.a.a.a.a.a.a.a/*5*/
////
//// interface B { [s: string]: B }
//// declare let b: B;
//// const oub/*6*/ = foo/*7*/(b);
//// oub.b/*8*/
//// oub.b.b/*9*/
//// oub.b.a.n.a.n.a/*10*/
verify.quickInfoAt('1', `const out: {
a: any;
}`);
verify.quickInfoAt('2', `function foo<{
a: any;
}>(deep: Deep<{
a: any;
}>): {
a: any;
}`);
verify.quickInfoAt('3', `(property) a: {
a: any;
}`);
verify.quickInfoAt('4', `(property) a: {
a: any;
}`);
verify.quickInfoAt('5', `(property) a: {
a: any;
}`);
verify.quickInfoAt('6', `const oub: {
[x: string]: any;
}`);
verify.quickInfoAt('7', `function foo<{
[x: string]: any;
}>(deep: Deep<{
[x: string]: any;
}>): {
[x: string]: any;
}`);
verify.quickInfoAt('8', `{
[x: string]: any;
}`);
verify.quickInfoAt('9', `{
[x: string]: any;
}`);
verify.quickInfoAt('10', `{
[x: string]: any;
}`);