Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions tsc/internal/checker/nodebuilderimpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -2300,6 +2300,11 @@ func (b *NodeBuilderImpl) serializeTypeForDeclaration(declaration *ast.Declarati
var reportedInferenceFallback bool
// !!! expandable hover support
if !b.isActivelyExpanding() && tryReuse && b.ctx.enclosingDeclaration != nil && declaration != nil && (ast.IsAccessor(declaration) || (ast.HasInferredType(declaration) && !ast.NodeIsSynthesized(declaration) && (t.ObjectFlags()&ObjectFlagsRequiresWidening) == 0)) {
oldMapper := b.ctx.mapper
// The annotation belongs to the original declaration, not the instantiated symbol.
if symbol != nil && symbol.CheckFlags&ast.CheckFlagsInstantiated != 0 {
b.ctx.mapper = b.ch.combineTypeMappers(b.ch.valueSymbolLinks.Get(symbol).mapper, oldMapper)
}
Comment on lines +2305 to +2307
var remove func()
if symbol != nil {
remove = b.addSymbolTypeToContext(symbol, t)
Expand Down Expand Up @@ -2350,6 +2355,7 @@ func (b *NodeBuilderImpl) serializeTypeForDeclaration(declaration *ast.Declarati
if remove != nil {
remove()
}
b.ctx.mapper = oldMapper
}
if result == nil {
if reportedInferenceFallback {
Expand Down
2 changes: 1 addition & 1 deletion tsc/internal/checker/pseudotypenodebuilder.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (b *NodeBuilderImpl) pseudoTypeToNodeWithCheckerFallback(t *pseudochecker.P
return result
} else if t.Kind == pseudochecker.PseudoTypeKindDirect {
existing := t.AsPseudoTypeDirect().TypeNode
if !b.canReuseExistingJSTypeNode(existing, checkerType) {
if b.getTypeFromTypeNode(existing, true /*noMappedTypes*/) == nil || !b.canReuseExistingJSTypeNode(existing, checkerType) {
if !b.ctx.suppressReportInferenceFallback {
b.ctx.tracker.ReportInferenceFallback(existing)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//// [tests/cases/compiler/declarationEmitUninstantiatedConditionalTypeParameters.ts] ////

//// [contracts.js]
exports.schema = { parse: v => v };

//// [router.ts]
import { State } from "./contracts";
interface Builder<TOutputOut> {
query<T>(resolver: () => T): { output: TOutputOut extends "unset" ? T : TOutputOut };
}

declare const builder: Builder<"unset">;

export const query = builder.query((): State | null => null);
export const anyQuery = builder.query((): any => null);
export const typedQuery = builder.query((): string | null => null);




//// [router.d.ts]
export declare const query: {
output: any;
};
export declare const anyQuery: {
output: any;
};
export declare const typedQuery: {
output: string | null;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//// [tests/cases/compiler/declarationEmitUninstantiatedConditionalTypeParameters.ts] ////

=== router.ts ===
import { State } from "./contracts";
>State : Symbol(State, Decl(router.ts, 0, 8))

interface Builder<TOutputOut> {
>Builder : Symbol(Builder, Decl(router.ts, 0, 36))
>TOutputOut : Symbol(TOutputOut, Decl(router.ts, 1, 18))

query<T>(resolver: () => T): { output: TOutputOut extends "unset" ? T : TOutputOut };
>query : Symbol(Builder.query, Decl(router.ts, 1, 31))
>T : Symbol(T, Decl(router.ts, 2, 10))
>resolver : Symbol(resolver, Decl(router.ts, 2, 13))
>T : Symbol(T, Decl(router.ts, 2, 10))
>output : Symbol(output, Decl(router.ts, 2, 34))
>TOutputOut : Symbol(TOutputOut, Decl(router.ts, 1, 18))
>T : Symbol(T, Decl(router.ts, 2, 10))
>TOutputOut : Symbol(TOutputOut, Decl(router.ts, 1, 18))
}

declare const builder: Builder<"unset">;
>builder : Symbol(builder, Decl(router.ts, 5, 13))
>Builder : Symbol(Builder, Decl(router.ts, 0, 36))

export const query = builder.query((): State | null => null);
>query : Symbol(query, Decl(router.ts, 7, 12))
>builder.query : Symbol(Builder.query, Decl(router.ts, 1, 31))
>builder : Symbol(builder, Decl(router.ts, 5, 13))
>query : Symbol(Builder.query, Decl(router.ts, 1, 31))
>State : Symbol(State, Decl(router.ts, 0, 8))

export const anyQuery = builder.query((): any => null);
>anyQuery : Symbol(anyQuery, Decl(router.ts, 8, 12))
>builder.query : Symbol(Builder.query, Decl(router.ts, 1, 31))
>builder : Symbol(builder, Decl(router.ts, 5, 13))
>query : Symbol(Builder.query, Decl(router.ts, 1, 31))

export const typedQuery = builder.query((): string | null => null);
>typedQuery : Symbol(typedQuery, Decl(router.ts, 9, 12))
>builder.query : Symbol(Builder.query, Decl(router.ts, 1, 31))
>builder : Symbol(builder, Decl(router.ts, 5, 13))
>query : Symbol(Builder.query, Decl(router.ts, 1, 31))

Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//// [tests/cases/compiler/declarationEmitUninstantiatedConditionalTypeParameters.ts] ////

=== router.ts ===
import { State } from "./contracts";
>State : any

interface Builder<TOutputOut> {
query<T>(resolver: () => T): { output: TOutputOut extends "unset" ? T : TOutputOut };
>query : <T>(resolver: () => T) => { output: TOutputOut extends "unset" ? T : TOutputOut; }
>resolver : () => T
>output : TOutputOut extends "unset" ? T : TOutputOut
}

declare const builder: Builder<"unset">;
>builder : Builder<"unset">

export const query = builder.query((): State | null => null);
>query : { output: any; }
>builder.query((): State | null => null) : { output: any; }
>builder.query : <T>(resolver: () => T) => { output: T; }
>builder : Builder<"unset">
>query : <T>(resolver: () => T) => { output: T; }
>(): State | null => null : () => State | null

export const anyQuery = builder.query((): any => null);
>anyQuery : { output: any; }
>builder.query((): any => null) : { output: any; }
>builder.query : <T>(resolver: () => T) => { output: T; }
>builder : Builder<"unset">
>query : <T>(resolver: () => T) => { output: T; }
>(): any => null : () => any

export const typedQuery = builder.query((): string | null => null);
>typedQuery : { output: string | null; }
>builder.query((): string | null => null) : { output: string | null; }
>builder.query : <T>(resolver: () => T) => { output: T; }
>builder : Builder<"unset">
>query : <T>(resolver: () => T) => { output: T; }
>(): string | null => null : () => string | null

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ declare const p: Promise<number>;

p.finally();
>p.finally() : Promise<number>
>p.finally : (onfinally?: (() => void) | undefined | null) => Promise<number>
>p.finally : (onfinally?: (() => void) | null | undefined) => Promise<number>
>p : Promise<number>
>finally : (onfinally?: (() => void) | undefined | null) => Promise<number>
>finally : (onfinally?: (() => void) | null | undefined) => Promise<number>

Original file line number Diff line number Diff line change
Expand Up @@ -172,11 +172,11 @@ namespace TypeScript {

this.asts.pop();
>this.asts.pop() : TypeScript.AST
>this.asts.pop : () => TypeScript.AST | undefined
>this.asts.pop : () => TypeScript.AST
>this.asts : TypeScript.AST[]
>this : this
>asts : TypeScript.AST[]
>pop : () => TypeScript.AST | undefined
>pop : () => TypeScript.AST
}
return head;
>head : TypeScript.AST
Expand All @@ -201,11 +201,11 @@ namespace TypeScript {

this.asts.pop();
>this.asts.pop() : TypeScript.AST
>this.asts.pop : () => TypeScript.AST | undefined
>this.asts.pop : () => TypeScript.AST
>this.asts : TypeScript.AST[]
>this : this
>asts : TypeScript.AST[]
>pop : () => TypeScript.AST | undefined
>pop : () => TypeScript.AST
}
this.top = this.asts.length;
>this.top = this.asts.length : number
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2178,11 +2178,11 @@ namespace TypeScript {

context.modDeclChain.pop();
>context.modDeclChain.pop() : any
>context.modDeclChain.pop : () => ModuleDeclaration | undefined
>context.modDeclChain.pop : () => any
>context.modDeclChain : ModuleDeclaration[]
>context : AssignScopeContext
>modDeclChain : ModuleDeclaration[]
>pop : () => ModuleDeclaration | undefined
>pop : () => any

if (context.modDeclChain.length >= 1) {
>context.modDeclChain.length >= 1 : boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@
let promise1 = new Promise(function(resolve, reject) {})
>promise1 : Promise<unknown>
>new Promise(function(resolve, reject) {}) .finally(function() {}) : Promise<unknown>
>new Promise(function(resolve, reject) {}) .finally : (onfinally?: (() => void) | undefined | null) => Promise<unknown>
>new Promise(function(resolve, reject) {}) .finally : (onfinally?: (() => void) | null | undefined) => Promise<unknown>
>new Promise(function(resolve, reject) {}) : Promise<unknown>
>Promise : PromiseConstructor
>function(resolve, reject) {} : (resolve: (value: unknown) => void, reject: (reason?: any) => void) => void
>resolve : (value: unknown) => void
>reject : (reason?: any) => void

.finally(function() {});
>finally : (onfinally?: (() => void) | undefined | null) => Promise<unknown>
>finally : (onfinally?: (() => void) | null | undefined) => Promise<unknown>
>function() {} : () => void

Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
//// [declarationEmitUnresolvedGenericAnnotations.ts] ////
import type { Box, Schema } from "./external";

export const identity = <T extends Schema>(value: Box<T>): Box<T> => value;
export const nullable = <T>(value: Box<T> | null): Box<T> | null => value;
export const conditional = <T>(value: T): T extends string ? Box<T> : T => null!;
export const mapped = <T>(value: T): { [K in keyof T]: Box<T[K]> } => null!;

export const methods = {
identity<T extends Schema>(value: Box<T>): Box<T> {
return value;
},
conditional<T>(value: T): T extends string ? Box<T> : T {
return null!;
}
};

export class Container<T extends Schema> {
value: Box<T>;

constructor(value: Box<T>) {
this.value = value;
}

map<U extends Schema>(value: Box<U>): Box<U> {
return value;
}
}
//// [declarationEmitUnresolvedGenericAnnotations.d.ts] ////
import type { Box, Schema } from "./external";
export declare const identity: <T extends Schema>(value: Box<T>) => Box<T>;
export declare const nullable: <T>(value: Box<T> | null) => Box<T> | null;
export declare const conditional: <T>(value: T) => T extends string ? Box<T> : T;
export declare const mapped: <T>(value: T) => { [K in keyof T]: Box<T[K]>; };
export declare const methods: {
identity<T extends Schema>(value: Box<T>): Box<T>;
conditional<T>(value: T): T extends string ? Box<T> : T;
};
export declare class Container<T extends Schema> {
value: Box<T>;
constructor(value: Box<T>);
map<U extends Schema>(value: Box<U>): Box<U>;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// @declaration: true
// @emitDeclarationOnly: true
// @strictNullChecks: true
// @noImplicitAny: false
// @module: commonjs
// @noImplicitReferences: true

// @filename: contracts.js
exports.schema = { parse: v => v };

// @filename: router.ts
import { State } from "./contracts";
interface Builder<TOutputOut> {
query<T>(resolver: () => T): { output: TOutputOut extends "unset" ? T : TOutputOut };
Comment on lines +13 to +14
}

declare const builder: Builder<"unset">;

export const query = builder.query((): State | null => null);
export const anyQuery = builder.query((): any => null);
export const typedQuery = builder.query((): string | null => null);
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// @strict: true
// @declaration: true
// @emitDeclarationOnly: true

import type { Box, Schema } from "./external";

export const identity = <T extends Schema>(value: Box<T>): Box<T> => value;
export const nullable = <T>(value: Box<T> | null): Box<T> | null => value;
export const conditional = <T>(value: T): T extends string ? Box<T> : T => null!;
export const mapped = <T>(value: T): { [K in keyof T]: Box<T[K]> } => null!;

export const methods = {
identity<T extends Schema>(value: Box<T>): Box<T> {
return value;
},
conditional<T>(value: T): T extends string ? Box<T> : T {
return null!;
}
};

export class Container<T extends Schema> {
value: Box<T>;

constructor(value: Box<T>) {
this.value = value;
}

map<U extends Schema>(value: Box<U>): Box<U> {
return value;
}
}
Loading