Skip to content

Commit 391f9ff

Browse files
authored
Strict optional properties (#43947)
* Introduce --strictOptionalProperties compiler switch * Accept new baselines * Removing missingType when printing back optional properties * Accept new baselines * Fix linting issue * Use getNonMissingTypeOfSymbol in getTypeOfSymbolAtLocation * Properly elaborate errors involving optional properties * Accept new baselines * Properly check optional properties in tuple types * Accept new baselines * Add missing tuple type check * More permissive check of strict optional properties and index signatures * Add tests * Fix lint issues * Accept new baselines
1 parent b603a04 commit 391f9ff

File tree

90 files changed

+2965
-787
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

90 files changed

+2965
-787
lines changed

src/compiler/checker.ts

+101-83
Large diffs are not rendered by default.

src/compiler/commandLineParser.ts

+9
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,15 @@ namespace ts {
612612
category: Diagnostics.Strict_Type_Checking_Options,
613613
description: Diagnostics.Enable_strict_checking_of_property_initialization_in_classes
614614
},
615+
{
616+
name: "strictOptionalProperties",
617+
type: "boolean",
618+
affectsSemanticDiagnostics: true,
619+
strictFlag: true,
620+
showInSimplifiedHelpView: true,
621+
category: Diagnostics.Strict_Type_Checking_Options,
622+
description: Diagnostics.Enable_strict_checking_of_optional_properties
623+
},
615624
{
616625
name: "noImplicitThis",
617626
type: "boolean",

src/compiler/diagnosticMessages.json

+4
Original file line numberDiff line numberDiff line change
@@ -4877,6 +4877,10 @@
48774877
"category": "Message",
48784878
"code": 6242
48794879
},
4880+
"Enable strict checking of optional properties.": {
4881+
"category": "Message",
4882+
"code": 6243
4883+
},
48804884

48814885
"Projects to reference": {
48824886
"category": "Message",

src/compiler/program.ts

+3
Original file line numberDiff line numberDiff line change
@@ -3043,6 +3043,9 @@ namespace ts {
30433043
if (options.strictPropertyInitialization && !getStrictOptionValue(options, "strictNullChecks")) {
30443044
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "strictPropertyInitialization", "strictNullChecks");
30453045
}
3046+
if (options.strictOptionalProperties && !getStrictOptionValue(options, "strictNullChecks")) {
3047+
createDiagnosticForOptionName(Diagnostics.Option_0_cannot_be_specified_without_specifying_option_1, "strictOptionalProperties", "strictNullChecks");
3048+
}
30463049

30473050
if (options.isolatedModules) {
30483051
if (options.out) {

src/compiler/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -6041,6 +6041,7 @@ namespace ts {
60416041
strictBindCallApply?: boolean; // Always combine with strict property
60426042
strictNullChecks?: boolean; // Always combine with strict property
60436043
strictPropertyInitialization?: boolean; // Always combine with strict property
6044+
strictOptionalProperties?: boolean; // Always combine with strict property
60446045
stripInternal?: boolean;
60456046
suppressExcessPropertyErrors?: boolean;
60466047
suppressImplicitAnyIndexErrors?: boolean;

src/compiler/utilities.ts

+1
Original file line numberDiff line numberDiff line change
@@ -6086,6 +6086,7 @@ namespace ts {
60866086
| "strictFunctionTypes"
60876087
| "strictBindCallApply"
60886088
| "strictPropertyInitialization"
6089+
| "strictOptionalProperties"
60896090
| "alwaysStrict"
60906091
;
60916092

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

+1
Original file line numberDiff line numberDiff line change
@@ -2913,6 +2913,7 @@ declare namespace ts {
29132913
strictBindCallApply?: boolean;
29142914
strictNullChecks?: boolean;
29152915
strictPropertyInitialization?: boolean;
2916+
strictOptionalProperties?: boolean;
29162917
stripInternal?: boolean;
29172918
suppressExcessPropertyErrors?: boolean;
29182919
suppressImplicitAnyIndexErrors?: boolean;

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

+1
Original file line numberDiff line numberDiff line change
@@ -2913,6 +2913,7 @@ declare namespace ts {
29132913
strictBindCallApply?: boolean;
29142914
strictNullChecks?: boolean;
29152915
strictPropertyInitialization?: boolean;
2916+
strictOptionalProperties?: boolean;
29162917
stripInternal?: boolean;
29172918
suppressExcessPropertyErrors?: boolean;
29182919
suppressImplicitAnyIndexErrors?: boolean;

tests/baselines/reference/checkJsxIntersectionElementPropsType.types

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ declare class Component<P> {
1616

1717
class C<T> extends Component<{ x?: boolean; } & T> {}
1818
>C : C<T>
19-
>Component : Component<{ x?: boolean | undefined; } & T>
19+
>Component : Component<{ x?: boolean; } & T>
2020
>x : boolean | undefined
2121

2222
const y = new C({foobar: "example"});

tests/baselines/reference/circularlyConstrainedMappedTypeContainingConditionalNoInfiniteInstantiationDepth.types

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ declare class Component<P> {
1010
>context : any
1111

1212
readonly props: Readonly<P> & Readonly<{ children?: {} }>;
13-
>props : Readonly<P> & Readonly<{ children?: {} | undefined; }>
13+
>props : Readonly<P> & Readonly<{ children?: {}; }>
1414
>children : {} | undefined
1515
}
1616
interface ComponentClass<P = {}> {
@@ -29,7 +29,7 @@ interface ComponentClass<P = {}> {
2929
}
3030
interface FunctionComponent<P = {}> {
3131
(props: P & { children?: {} }, context?: any): {} | null;
32-
>props : P & { children?: {} | undefined; }
32+
>props : P & { children?: {}; }
3333
>children : {} | undefined
3434
>context : any
3535
>null : null

tests/baselines/reference/contextuallyTypedParametersWithInitializers.types

+5-5
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ declare function id3<T extends (x: { foo: any }) => any>(input: T): T;
1616

1717
declare function id4<T extends (x: { foo?: number }) => any>(input: T): T;
1818
>id4 : <T extends (x: { foo?: number;}) => any>(input: T) => T
19-
>x : { foo?: number | undefined; }
19+
>x : { foo?: number; }
2020
>foo : number | undefined
2121
>input : T
2222

@@ -60,10 +60,10 @@ const f13 = id3(function ({ foo = 42 }) { return foo });
6060
>foo : any
6161

6262
const f14 = id4(function ({ foo = 42 }) { return foo });
63-
>f14 : ({ foo }: { foo?: number | undefined; }) => number
64-
>id4(function ({ foo = 42 }) { return foo }) : ({ foo }: { foo?: number | undefined; }) => number
65-
>id4 : <T extends (x: { foo?: number | undefined; }) => any>(input: T) => T
66-
>function ({ foo = 42 }) { return foo } : ({ foo }: { foo?: number | undefined; }) => number
63+
>f14 : ({ foo }: { foo?: number; }) => number
64+
>id4(function ({ foo = 42 }) { return foo }) : ({ foo }: { foo?: number; }) => number
65+
>id4 : <T extends (x: { foo?: number; }) => any>(input: T) => T
66+
>function ({ foo = 42 }) { return foo } : ({ foo }: { foo?: number; }) => number
6767
>foo : number
6868
>42 : 42
6969
>foo : number

0 commit comments

Comments
 (0)