Skip to content
Merged
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
9 changes: 3 additions & 6 deletions internal/compiler/program.go
Original file line number Diff line number Diff line change
Expand Up @@ -671,12 +671,9 @@ func (p *Program) verifyCompilerOptions() {
createRemovedOptionDiagnostic("outFile", "", "")
}

// if options.Target == core.ScriptTargetES3 {
// createRemovedOptionDiagnostic("target", "ES3", "")
// }
// if options.Target == core.ScriptTargetES5 {
// createRemovedOptionDiagnostic("target", "ES5", "")
// }
if options.Target == core.ScriptTargetES5 {
createRemovedOptionDiagnostic("target", "ES5", "")
}

if options.Module == core.ModuleKindAMD {
createRemovedOptionDiagnostic("module", "AMD", "")
Expand Down
6 changes: 3 additions & 3 deletions internal/core/compileroptions.go
Original file line number Diff line number Diff line change
Expand Up @@ -513,9 +513,9 @@ func (newLine NewLineKind) GetNewLineCharacter() string {
type ScriptTarget int32

const (
ScriptTargetNone ScriptTarget = 0
ScriptTargetES3 ScriptTarget = 0 // Deprecated
ScriptTargetES5 ScriptTarget = 1 // Deprecated
ScriptTargetNone ScriptTarget = 0
// Deprecated: Do not use outside of options parsing and validation.
ScriptTargetES5 ScriptTarget = 1
ScriptTargetES2015 ScriptTarget = 2
ScriptTargetES2016 ScriptTarget = 3
ScriptTargetES2017 ScriptTarget = 4
Expand Down
1 change: 0 additions & 1 deletion internal/core/scripttarget_stringer_generated.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions internal/testrunner/compiler_runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ var skippedTests = []string{
// Flaky
"for-of29.ts",

// Fails with concurrent checking.
"controlFlowFunctionLikeCircular1.ts",

// These tests contain options that have been completely removed, so fail to parse.
"preserveUnusedImports.ts",
"noCrashWithVerbatimModuleSyntaxAndImportsNotUsedAsValues.ts",
Expand Down
41 changes: 32 additions & 9 deletions internal/testutil/harnessutil/harnessutil.go
Original file line number Diff line number Diff line change
Expand Up @@ -429,8 +429,6 @@ func parseHarnessOption(t *testing.T, key string, value any, harnessOptions *Har
}
}

var deprecatedModuleResolution []string = []string{"node", "classic", "node10"}

func getOptionValue(t *testing.T, option *tsoptions.CommandLineOption, value string, cwd string) tsoptions.CompilerOptionsValue {
switch option.Kind {
case tsoptions.CommandLineOptionTypeString:
Expand Down Expand Up @@ -1103,7 +1101,12 @@ func splitOptionValues(t *testing.T, value string, option string) []string {

// remove all excluded entries
for _, exclude := range excludes {
value := getValueOfOptionString(t, option, exclude)
value, ok := tryGetValueOfOptionString(option, exclude)
if !ok {
// The excluded value is not recognized (e.g., a removed option like "es3").
// Just skip it since there's nothing to remove.
continue
}
delete(variations, value)
}

Expand All @@ -1114,15 +1117,35 @@ func splitOptionValues(t *testing.T, value string, option string) []string {
}

func getValueOfOptionString(t *testing.T, option string, value string) tsoptions.CompilerOptionsValue {
result, ok := tryGetValueOfOptionString(option, value)
if !ok {
t.Fatalf("Unknown value '%s' for option '%s'", value, option)
}
return result
}

func tryGetValueOfOptionString(option string, value string) (tsoptions.CompilerOptionsValue, bool) {
optionDecl := getCommandLineOption(option)
if optionDecl == nil {
t.Fatalf("Unknown option '%s'", option)
return nil, false
}
// TODO(gabritto): remove this when we deprecate the tests containing those option values
if optionDecl.Name == "moduleResolution" && slices.Contains(deprecatedModuleResolution, strings.ToLower(value)) {
return value
switch optionDecl.Kind {
case tsoptions.CommandLineOptionTypeEnum:
enumVal, ok := optionDecl.EnumMap().Get(strings.ToLower(value))
if !ok {
return nil, false
}
return enumVal, true
case tsoptions.CommandLineOptionTypeBoolean:
switch strings.ToLower(value) {
case "true":
return true, true
case "false":
return false, true
}
return nil, false
}
return getOptionValue(t, optionDecl, value, "/")
return value, true
}

func getCommandLineOption(option string) *tsoptions.CommandLineOption {
Expand Down Expand Up @@ -1202,7 +1225,7 @@ func SkipUnsupportedCompilerOptions(t *testing.T, options *core.CompilerOptions)
t.Skipf("unsupported outFile %s", options.OutFile)
}
switch options.Target {
case core.ScriptTargetES3, core.ScriptTargetES5:
case core.ScriptTargetES5:
t.Skipf("unsupported target %s", options.Target)
}
}
2 changes: 1 addition & 1 deletion internal/tsoptions/commandlineoption.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ var commandLineOptionEnumMap = map[string]*collections.OrderedMap[string, any]{
// CommandLineOption.DeprecatedKeys()
var commandLineOptionDeprecated = map[string]*collections.Set[string]{
"moduleResolution": collections.NewSetFromItems("node", "classic", "node10"),
"target": collections.NewSetFromItems("es3", "es5"),
"target": collections.NewSetFromItems("es5"),
}

// todo: revisit to see if this can be improved
Expand Down
1 change: 0 additions & 1 deletion internal/tsoptions/enummaps.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,6 @@ var moduleResolutionOptionMap = collections.NewOrderedMapFromList([]collections.
})

var targetOptionMap = collections.NewOrderedMapFromList([]collections.MapEntry[string, any]{
{Key: "es3", Value: core.ScriptTargetES3},
{Key: "es5", Value: core.ScriptTargetES5},
{Key: "es6", Value: core.ScriptTargetES2015},
{Key: "es2015", Value: core.ScriptTargetES2015},
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
b.d.ts(1,17): error TS7010: 'foo', which lacks return-type annotation, implicitly has an 'any' return type.
b.d.ts(3,17): error TS7010: 'bar', which lacks return-type annotation, implicitly has an 'any' return type.


==== b.d.ts (2 errors) ====
export function foo();
~~~
!!! error TS7010: 'foo', which lacks return-type annotation, implicitly has an 'any' return type.

export function bar();
~~~
!!! error TS7010: 'bar', which lacks return-type annotation, implicitly has an 'any' return type.

==== a.ts (0 errors) ====
import { default as Foo } from "./b";
Foo.bar();
Foo.foo();
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//// [tests/cases/compiler/allowSyntheticDefaultImports9.ts] ////

//// [b.d.ts]
export function foo();

export function bar();

//// [a.ts]
import { default as Foo } from "./b";
Foo.bar();
Foo.foo();

//// [a.js]
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const b_1 = __importDefault(require("./b"));
b_1.default.bar();
b_1.default.foo();
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//// [tests/cases/compiler/allowSyntheticDefaultImports9.ts] ////

=== b.d.ts ===
export function foo();
>foo : Symbol(foo, Decl(b.d.ts, 0, 0))

export function bar();
>bar : Symbol(bar, Decl(b.d.ts, 0, 22))

=== a.ts ===
import { default as Foo } from "./b";
>default : Symbol(Foo, Decl(b.d.ts, 0, 0))
>Foo : Symbol(Foo, Decl(a.ts, 0, 8))

Foo.bar();
>Foo.bar : Symbol(Foo.bar, Decl(b.d.ts, 0, 22))
>Foo : Symbol(Foo, Decl(a.ts, 0, 8))
>bar : Symbol(Foo.bar, Decl(b.d.ts, 0, 22))

Foo.foo();
>Foo.foo : Symbol(Foo.foo, Decl(b.d.ts, 0, 0))
>Foo : Symbol(Foo, Decl(a.ts, 0, 8))
>foo : Symbol(Foo.foo, Decl(b.d.ts, 0, 0))

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

=== b.d.ts ===
export function foo();
>foo : () => any

export function bar();
>bar : () => any

=== a.ts ===
import { default as Foo } from "./b";
>default : typeof Foo
>Foo : typeof Foo

Foo.bar();
>Foo.bar() : any
>Foo.bar : () => any
>Foo : typeof Foo
>bar : () => any

Foo.foo();
>Foo.foo() : any
>Foo.foo : () => any
>Foo : typeof Foo
>foo : () => any

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

=== assertionWithNoArgument.ts ===
export function assertWeird(value?: string): asserts value {
>assertWeird : Symbol(assertWeird, Decl(assertionWithNoArgument.ts, 0, 0))
>value : Symbol(value, Decl(assertionWithNoArgument.ts, 0, 28))
>value : Symbol(value, Decl(assertionWithNoArgument.ts, 0, 28))
}

assertWeird();
>assertWeird : Symbol(assertWeird, Decl(assertionWithNoArgument.ts, 0, 0))

assertWeird("hello");
>assertWeird : Symbol(assertWeird, Decl(assertionWithNoArgument.ts, 0, 0))

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

=== assertionWithNoArgument.ts ===
export function assertWeird(value?: string): asserts value {
>assertWeird : (value?: string | undefined) => asserts value
>value : string | undefined
}

assertWeird();
>assertWeird() : void
>assertWeird : (value?: string | undefined) => asserts value

assertWeird("hello");
>assertWeird("hello") : void
>assertWeird : (value?: string | undefined) => asserts value
>"hello" : "hello"

Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
assertsPredicateParameterMismatch.ts(7,12): error TS1225: Cannot find parameter 'condition'.


==== assertsPredicateParameterMismatch.ts (1 errors) ====
// This test verifies that the checker doesn't panic when an assertion predicate
// references a parameter name that doesn't match any actual function parameter.
// This specifically tests the code path in isReachableFlowNodeWorker.

function assertCondition(
_condition: boolean
): asserts condition { // "condition" doesn't match parameter "_condition"
~~~~~~~~~
!!! error TS1225: Cannot find parameter 'condition'.
if (!_condition) {
throw new Error('Condition failed');
}
}

function test(): void {
assertCondition(false);
console.log("unreachable");
}

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

=== assertsPredicateParameterMismatch.ts ===
// This test verifies that the checker doesn't panic when an assertion predicate
// references a parameter name that doesn't match any actual function parameter.
// This specifically tests the code path in isReachableFlowNodeWorker.

function assertCondition(
>assertCondition : Symbol(assertCondition, Decl(assertsPredicateParameterMismatch.ts, 0, 0))

_condition: boolean
>_condition : Symbol(_condition, Decl(assertsPredicateParameterMismatch.ts, 4, 25))

): asserts condition { // "condition" doesn't match parameter "_condition"
if (!_condition) {
>_condition : Symbol(_condition, Decl(assertsPredicateParameterMismatch.ts, 4, 25))

throw new Error('Condition failed');
>Error : Symbol(Error, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --), Decl(lib.es2022.error.d.ts, --, --))
}
}

function test(): void {
>test : Symbol(test, Decl(assertsPredicateParameterMismatch.ts, 10, 1))

assertCondition(false);
>assertCondition : Symbol(assertCondition, Decl(assertsPredicateParameterMismatch.ts, 0, 0))

console.log("unreachable");
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
}

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

=== assertsPredicateParameterMismatch.ts ===
// This test verifies that the checker doesn't panic when an assertion predicate
// references a parameter name that doesn't match any actual function parameter.
// This specifically tests the code path in isReachableFlowNodeWorker.

function assertCondition(
>assertCondition : (_condition: boolean) => asserts condition

_condition: boolean
>_condition : boolean

): asserts condition { // "condition" doesn't match parameter "_condition"
if (!_condition) {
>!_condition : boolean
>_condition : boolean

throw new Error('Condition failed');
>new Error('Condition failed') : Error
>Error : ErrorConstructor
>'Condition failed' : "Condition failed"
}
}

function test(): void {
>test : () => void

assertCondition(false);
>assertCondition(false) : void
>assertCondition : (_condition: boolean) => asserts condition
>false : false

console.log("unreachable");
>console.log("unreachable") : void
>console.log : (...data: any[]) => void
>console : Console
>log : (...data: any[]) => void
>"unreachable" : "unreachable"
}

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

=== /index.ts ===
// The automatic type directive "pkg" from @types should resolve to esm.d.mts
// because bundler resolution uses the "import" condition.
// If the wrong file is resolved, we'll get a type error due to conflicting declarations.
import type { PkgType } from "pkg";
>PkgType : Symbol(PkgType, Decl(index.ts, 3, 13))

// This should work if esm.d.mts is correctly resolved
const x: PkgType = { esm: true };
>x : Symbol(x, Decl(index.ts, 6, 5))
>PkgType : Symbol(PkgType, Decl(index.ts, 3, 13))
>esm : Symbol(esm, Decl(index.ts, 6, 20))

=== /node_modules/pkg/esm.d.mts ===
// This file should be resolved when using bundler resolution with "import" condition
export interface PkgType {
>PkgType : Symbol(PkgType, Decl(esm.d.mts, 0, 0))

esm: true;
>esm : Symbol(PkgType.esm, Decl(esm.d.mts, 1, 26))
}
declare global {
>global : Symbol(global, Decl(esm.d.mts, 3, 1))

var expectedCondition: "import";
>expectedCondition : Symbol(expectedCondition, Decl(esm.d.mts, 5, 7))
}

Loading
Loading