Skip to content

Commit 171a3ee

Browse files
committed
Per-file strictNullChecks support
1 parent ef3813c commit 171a3ee

29 files changed

+729
-436
lines changed

src/compiler/checker.ts

Lines changed: 378 additions & 263 deletions
Large diffs are not rendered by default.

src/compiler/types.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4386,9 +4386,9 @@ namespace ts {
43864386
/* @internal */ getParameterType(signature: Signature, parameterIndex: number): Type;
43874387
/* @internal */ getParameterIdentifierNameAtPosition(signature: Signature, parameterIndex: number): [parameterName: __String, isRestParameter: boolean] | undefined;
43884388
getNullableType(type: Type, flags: TypeFlags): Type;
4389-
getNonNullableType(type: Type): Type;
4389+
getNonNullableType(type: Type, context?: Node | undefined): Type;
43904390
/* @internal */ getNonOptionalType(type: Type): Type;
4391-
/* @internal */ isNullableType(type: Type): boolean;
4391+
/* @internal */ isNullableType(type: Type, context?: Node | undefined): boolean;
43924392
getTypeArguments(type: TypeReference): readonly Type[];
43934393

43944394
// TODO: GH#18217 `xToDeclaration` calls are frequently asserted as defined.
@@ -4520,8 +4520,8 @@ namespace ts {
45204520
/* @internal */ getFalseType(fresh?: boolean): Type;
45214521
/* @internal */ getTrueType(fresh?: boolean): Type;
45224522
/* @internal */ getVoidType(): Type;
4523-
/* @internal */ getUndefinedType(): Type;
4524-
/* @internal */ getNullType(): Type;
4523+
/* @internal */ getUndefinedType(widening?: boolean): Type;
4524+
/* @internal */ getNullType(widening?: boolean): Type;
45254525
/* @internal */ getESSymbolType(): Type;
45264526
/* @internal */ getNeverType(): Type;
45274527
/* @internal */ getOptionalType(): Type;
@@ -5416,12 +5416,12 @@ namespace ts {
54165416
Narrowable = Any | Unknown | StructuredOrInstantiable | StringLike | NumberLike | BigIntLike | BooleanLike | ESSymbol | UniqueESSymbol | NonPrimitive,
54175417
// The following flags are aggregated during union and intersection type construction
54185418
/* @internal */
5419-
IncludesMask = Any | Unknown | Primitive | Never | Object | Union | Intersection | NonPrimitive | TemplateLiteral,
5419+
IncludesMask = Any | Unknown | Primitive | Never | Object | Union | Intersection | NonPrimitive | TemplateLiteral | Index | StringMapping,
54205420
// The following flags are used for different purposes during union and intersection type construction
54215421
/* @internal */
54225422
IncludesMissingType = TypeParameter,
54235423
/* @internal */
5424-
IncludesNonWideningType = Index,
5424+
IncludesNonWideningType = 1 << 29, // repurpose for true typeflag when needed
54255425
/* @internal */
54265426
IncludesWildcard = IndexedAccess,
54275427
/* @internal */

src/services/codefixes/inferFromUsage.ts

Lines changed: 68 additions & 24 deletions
Large diffs are not rendered by default.

tests/baselines/reference/api/tsserverlibrary.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2323,7 +2323,7 @@ declare namespace ts {
23232323
getWidenedType(type: Type): Type;
23242324
getReturnTypeOfSignature(signature: Signature): Type;
23252325
getNullableType(type: Type, flags: TypeFlags): Type;
2326-
getNonNullableType(type: Type): Type;
2326+
getNonNullableType(type: Type, context?: Node | undefined): Type;
23272327
getTypeArguments(type: TypeReference): readonly Type[];
23282328
/** Note that the resulting nodes cannot be checked. */
23292329
typeToTypeNode(type: Type, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): TypeNode | undefined;

tests/baselines/reference/api/typescript.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2323,7 +2323,7 @@ declare namespace ts {
23232323
getWidenedType(type: Type): Type;
23242324
getReturnTypeOfSignature(signature: Signature): Type;
23252325
getNullableType(type: Type, flags: TypeFlags): Type;
2326-
getNonNullableType(type: Type): Type;
2326+
getNonNullableType(type: Type, context?: Node | undefined): Type;
23272327
getTypeArguments(type: TypeReference): readonly Type[];
23282328
/** Note that the resulting nodes cannot be checked. */
23292329
typeToTypeNode(type: Type, enclosingDeclaration: Node | undefined, flags: NodeBuilderFlags | undefined): TypeNode | undefined;

tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.errors.txt

Lines changed: 104 additions & 42 deletions
Large diffs are not rendered by default.

tests/baselines/reference/collectionPatternNoError.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ function fetchMsg<V extends Message>(protoCtor: MsgConstructor<V>): V {
2323
>protoCtor : MsgConstructor<V>
2424

2525
return null!;
26-
>null! : null
26+
>null! : never
2727
>null : null
2828
}
2929

tests/baselines/reference/conditionalTypes2.errors.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ tests/cases/conformance/types/conditional/conditionalTypes2.ts(75,12): error TS2
148148
!!! error TS2345: Property 'bat' is missing in type 'Bar & Foo' but required in type '{ foo: string; bat: string; }'.
149149
!!! error TS2345: Type 'Extract<T, Bar>' is not assignable to type '{ foo: string; bat: string; }'.
150150
!!! error TS2345: Property 'bat' is missing in type 'Bar & Foo' but required in type '{ foo: string; bat: string; }'.
151-
!!! related TS2728 tests/cases/conformance/types/conditional/conditionalTypes2.ts:62:43: 'bat' is declared here.
152151
!!! related TS2728 tests/cases/conformance/types/conditional/conditionalTypes2.ts:62:43: 'bat' is declared here.
153152
fooBat(y); // Error
154153
~

tests/baselines/reference/declarationEmitMappedTypeDistributivityPreservesConstraints.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ function fn<T extends { x: Map<T['x']> }>(sliceIndex: T): AllArg<T['x']> {
1515
>sliceIndex : T
1616

1717
return null!;
18-
>null! : null
18+
>null! : never
1919
>null : null
2020
}
2121

tests/baselines/reference/emitDecoratorMetadata_isolatedModules(module=commonjs).types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ class HelloWorld {
8080
handleEvent3(event: C3): T1 { return undefined! } // Ok, Error
8181
>handleEvent3 : (event: C3) => T1
8282
>event : C3
83-
>undefined! : undefined
83+
>undefined! : never
8484
>undefined : undefined
8585
}
8686

tests/baselines/reference/emitDecoratorMetadata_isolatedModules(module=esnext).types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ class HelloWorld {
8080
handleEvent3(event: C3): T1 { return undefined! } // Ok, Error
8181
>handleEvent3 : (event: C3) => T1
8282
>event : C3
83-
>undefined! : undefined
83+
>undefined! : never
8484
>undefined : undefined
8585
}
8686

tests/baselines/reference/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.errors.txt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcre
99
Type 'unknown' is not assignable to type 'A'.
1010
Type 'ReturnType<FunctionsObj<T>[string]>' is not assignable to type 'A'.
1111
Type 'unknown' is not assignable to type 'A'.
12-
Property 'x' is missing in type '{}' but required in type 'A'.
12+
Type 'unknown' is not assignable to type 'A'.
1313

1414

1515
==== tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts (1 errors) ====
@@ -38,8 +38,7 @@ tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcre
3838
!!! error TS2322: Type 'unknown' is not assignable to type 'A'.
3939
!!! error TS2322: Type 'ReturnType<FunctionsObj<T>[string]>' is not assignable to type 'A'.
4040
!!! error TS2322: Type 'unknown' is not assignable to type 'A'.
41-
!!! error TS2322: Property 'x' is missing in type '{}' but required in type 'A'.
42-
!!! related TS2728 tests/cases/compiler/genericConditionalConstrainedToUnknownNotAssignableToConcreteObject.ts:1:15: 'x' is declared here.
41+
!!! error TS2322: Type 'unknown' is not assignable to type 'A'.
4342
}
4443

4544
// Original CFA report of the above issue

tests/baselines/reference/inDoesNotOperateOnPrimitiveTypes.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ function union2<T extends object, U extends string | number>(thing: T | U) {
7979
"key" in thing; // Ok
8080
>"key" in thing : boolean
8181
>"key" : "key"
82-
>thing : T
82+
>thing : T | (T & null) | (U & null)
8383
}
8484
}
8585

@@ -146,7 +146,7 @@ function union5<T extends object | string, U extends object | number>(p: T | U)
146146
"key" in p;
147147
>"key" in p : boolean
148148
>"key" : "key"
149-
>p : (T & object) | (U & object)
149+
>p : (T & object) | (U & object) | (T & null) | (U & null)
150150
}
151151
}
152152

tests/baselines/reference/intersectionReduction.types

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,12 @@ type N1 = 'a' & 'b';
4040
>N1 : never
4141

4242
type N2 = { a: string } & null;
43-
>N2 : null
43+
>N2 : never
4444
>a : string
4545
>null : null
4646

4747
type N3 = { a: string } & undefined;
48-
>N3 : undefined
48+
>N3 : never
4949
>a : string
5050

5151
type N4 = string & number;
@@ -255,10 +255,10 @@ declare let s2: string & Tag2;
255255
>s2 : never
256256

257257
declare let t1: string & Tag1 | undefined;
258-
>t1 : undefined
258+
>t1 : never
259259

260260
declare let t2: string & Tag2 | undefined;
261-
>t2 : undefined
261+
>t2 : never
262262

263263
s1 = s2;
264264
>s1 = s2 : never
@@ -271,14 +271,14 @@ s2 = s1;
271271
>s1 : never
272272

273273
t1 = t2;
274-
>t1 = t2 : undefined
275-
>t1 : undefined
276-
>t2 : undefined
274+
>t1 = t2 : never
275+
>t1 : never
276+
>t2 : never
277277

278278
t2 = t1;
279-
>t2 = t1 : undefined
280-
>t2 : undefined
281-
>t1 : undefined
279+
>t2 = t1 : never
280+
>t2 : never
281+
>t1 : never
282282

283283
// Repro from #36736
284284

tests/baselines/reference/localTypeParameterInferencePriority.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class Table<S extends Schema> {
2020
>getRows : <C extends keyof S>() => Array<UnrollOnHover<Pick<S, C>>>
2121

2222
return null!
23-
>null! : null
23+
>null! : never
2424
>null : null
2525
}
2626
}

tests/baselines/reference/mappedTypeRelationships.errors.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,18 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(40,5): error TS2
1717
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(41,5): error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T] | undefined'.
1818
Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'U[keyof T] | undefined'.
1919
Type 'T[string]' is not assignable to type 'U[keyof T] | undefined'.
20+
Type 'T[string]' is not assignable to type 'U[keyof T]'.
21+
Type 'T' is not assignable to type 'U'.
22+
'U' could be instantiated with an arbitrary type which could be unrelated to 'T'.
2023
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(45,5): error TS2322: Type 'U[K] | undefined' is not assignable to type 'T[K]'.
2124
Type 'undefined' is not assignable to type 'T[K]'.
2225
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(46,5): error TS2322: Type 'T[K]' is not assignable to type 'U[K] | undefined'.
2326
Type 'T[keyof T]' is not assignable to type 'U[K] | undefined'.
2427
Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'U[K] | undefined'.
2528
Type 'T[string]' is not assignable to type 'U[K] | undefined'.
29+
Type 'T[string]' is not assignable to type 'U[K]'.
30+
Type 'T' is not assignable to type 'U'.
31+
'U' could be instantiated with an arbitrary type which could be unrelated to 'T'.
2632
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(51,5): error TS2542: Index signature in type 'Readonly<T>' only permits reading.
2733
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(56,5): error TS2542: Index signature in type 'Readonly<T>' only permits reading.
2834
tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(61,5): error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T]'.
@@ -146,6 +152,10 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS
146152
!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[keyof T] | undefined'.
147153
!!! error TS2322: Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'U[keyof T] | undefined'.
148154
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T] | undefined'.
155+
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[keyof T]'.
156+
!!! error TS2322: Type 'T' is not assignable to type 'U'.
157+
!!! error TS2322: 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'.
158+
!!! related TS2208 tests/cases/conformance/types/mapped/mappedTypeRelationships.ts:39:14: This type parameter might need an `extends U` constraint.
149159
}
150160

151161
function f13<T, U extends T, K extends keyof T>(x: T, y: Partial<U>, k: K) {
@@ -159,6 +169,10 @@ tests/cases/conformance/types/mapped/mappedTypeRelationships.ts(168,5): error TS
159169
!!! error TS2322: Type 'T[keyof T]' is not assignable to type 'U[K] | undefined'.
160170
!!! error TS2322: Type 'T[string] | T[number] | T[symbol]' is not assignable to type 'U[K] | undefined'.
161171
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K] | undefined'.
172+
!!! error TS2322: Type 'T[string]' is not assignable to type 'U[K]'.
173+
!!! error TS2322: Type 'T' is not assignable to type 'U'.
174+
!!! error TS2322: 'U' could be instantiated with an arbitrary type which could be unrelated to 'T'.
175+
!!! related TS2208 tests/cases/conformance/types/mapped/mappedTypeRelationships.ts:44:14: This type parameter might need an `extends U` constraint.
162176
}
163177

164178
function f20<T>(x: T, y: Readonly<T>, k: keyof T) {

tests/baselines/reference/metadataOfUnionWithNull.types

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ class B {
5454
>PropDeco : (target: Object, propKey: string | symbol) => void
5555

5656
d: undefined | null;
57-
>d : null
57+
>d : never
5858
>null : null
5959

6060
@PropDeco

tests/baselines/reference/noImplicitAnyForIn.types

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,8 @@ for (var a in x) {
5959
>b : any
6060

6161
var c = a || b;
62-
>c : string
63-
>a || b : string
62+
>c : string | undefined
63+
>a || b : string | undefined
6464
>a : string
6565
>b : undefined
6666
}

tests/baselines/reference/nonNullableReductionNonStrict.types

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ function test<T>(f1: Transform1<T>, f2: Transform2<T>) {
1717

1818
f1?.("hello");
1919
>f1?.("hello") : T
20-
>f1 : (value: string) => T
20+
>f1 : ((value: string) => T) | undefined
2121
>"hello" : "hello"
2222

2323
f2?.("hello");
@@ -28,23 +28,23 @@ function test<T>(f1: Transform1<T>, f2: Transform2<T>) {
2828

2929
function f1<T>(x: T | (string extends T ? null | undefined : never)) {
3030
>f1 : <T>(x: T | (string extends T ? null | undefined : never)) => void
31-
>x : T | (string extends T ? null : never)
31+
>x : T | (string extends T ? never : never)
3232
>null : null
3333

3434
let z = x!; // NonNullable<T>
35-
>z : T | (string extends T ? null : never)
36-
>x! : T | (string extends T ? null : never)
37-
>x : T | (string extends T ? null : never)
35+
>z : T
36+
>x! : T
37+
>x : T | (string extends T ? never : never)
3838
}
3939

4040
function f2<T, U extends null | undefined>(x: T | U) {
41-
>f2 : <T, U extends null>(x: T | U) => void
41+
>f2 : <T, U extends never>(x: T | U) => void
4242
>null : null
4343
>x : T | U
4444

4545
let z = x!; // NonNullable<T>
46-
>z : T | U
47-
>x! : T | U
46+
>z : T
47+
>x! : T
4848
>x : T | U
4949
}
5050

tests/baselines/reference/nullishCoalescingOperator_not_strict.types

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ declare const a7: unknown | null
3030
>null : null
3131

3232
declare const a8: never | null
33-
>a8 : null
33+
>a8 : never
3434
>null : null
3535

3636
declare const a9: any | null
@@ -81,9 +81,9 @@ const aa7 = a7 ?? 'whatever'
8181
>'whatever' : "whatever"
8282

8383
const aa8 = a8 ?? 'whatever'
84-
>aa8 : "whatever"
85-
>a8 ?? 'whatever' : "whatever"
86-
>a8 : null
84+
>aa8 : never
85+
>a8 ?? 'whatever' : never
86+
>a8 : never
8787
>'whatever' : "whatever"
8888

8989
const aa9 = a9 ?? 'whatever'

tests/baselines/reference/privateFieldAssignabilityFromUnknown.errors.txt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
tests/cases/compiler/privateFieldAssignabilityFromUnknown.ts(2,3): error TS18028: Private identifiers are only available when targeting ECMAScript 2015 and higher.
2-
tests/cases/compiler/privateFieldAssignabilityFromUnknown.ts(5,7): error TS2741: Property '#field' is missing in type '{}' but required in type 'Class'.
2+
tests/cases/compiler/privateFieldAssignabilityFromUnknown.ts(5,7): error TS2322: Type 'unknown' is not assignable to type 'Class'.
33

44

55
==== tests/cases/compiler/privateFieldAssignabilityFromUnknown.ts (2 errors) ====
@@ -11,6 +11,5 @@ tests/cases/compiler/privateFieldAssignabilityFromUnknown.ts(5,7): error TS2741:
1111

1212
const task: Class = {} as unknown;
1313
~~~~
14-
!!! error TS2741: Property '#field' is missing in type '{}' but required in type 'Class'.
15-
!!! related TS2728 tests/cases/compiler/privateFieldAssignabilityFromUnknown.ts:2:3: '#field' is declared here.
14+
!!! error TS2322: Type 'unknown' is not assignable to type 'Class'.
1615

tests/baselines/reference/propertyAccessOnTypeParameterWithoutConstraints.symbols

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,6 @@ var r3: string = a().toString();
7272
var r3b: string = a()['toString']();
7373
>r3b : Symbol(r3b, Decl(propertyAccessOnTypeParameterWithoutConstraints.ts, 21, 3))
7474
>a : Symbol(a, Decl(propertyAccessOnTypeParameterWithoutConstraints.ts, 17, 3))
75-
>'toString' : Symbol(Object.toString, Decl(lib.es5.d.ts, --, --))
7675

7776
var b = {
7877
>b : Symbol(b, Decl(propertyAccessOnTypeParameterWithoutConstraints.ts, 23, 3))

0 commit comments

Comments
 (0)