Allow literal initializers of readonly properties in declaration files (#26313)

* Allow literal initializers of readonly properties in declaration files

* Move some conditions a bit
This commit is contained in:
Wesley Wigham
2018-09-05 11:30:05 -07:00
committed by GitHub
parent bcb815b3ac
commit 62d8b85f1d
16 changed files with 147 additions and 89 deletions

View File

@@ -21708,7 +21708,7 @@ namespace ts {
const initializer = getEffectiveInitializer(declaration)!;
const type = getTypeOfExpression(initializer, /*cache*/ true);
const widened = getCombinedNodeFlags(declaration) & NodeFlags.Const ||
(getCombinedModifierFlags(declaration) & ModifierFlags.Readonly && !isParameterPropertyDeclaration(declaration)) ||
isDeclarationReadonly(declaration) ||
isTypeAssertion(initializer) ? type : getWidenedLiteralType(type);
if (isInJavaScriptFile(declaration)) {
if (widened.flags & TypeFlags.Nullable) {
@@ -28082,7 +28082,7 @@ namespace ts {
}
function isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean {
if (isVariableDeclaration(node) && isVarConst(node)) {
if (isDeclarationReadonly(node) || isVariableDeclaration(node) && isVarConst(node)) {
const type = getTypeOfSymbol(getSymbolOfNode(node));
return !!(type.flags & TypeFlags.StringOrNumberLiteral && type.flags & TypeFlags.FreshLiteral);
}
@@ -29420,26 +29420,28 @@ namespace ts {
(<PrefixUnaryExpression>expr).operand.kind === SyntaxKind.NumericLiteral;
}
function checkAmbientInitializer(node: VariableDeclaration | PropertyDeclaration | PropertySignature) {
if (node.initializer) {
const isInvalidInitializer = !isStringOrNumberLiteralExpression(node.initializer);
const isConstOrReadonly = isDeclarationReadonly(node) || isVariableDeclaration(node) && isVarConst(node);
if (isConstOrReadonly && !node.type) {
if (isInvalidInitializer) {
return grammarErrorOnNode(node.initializer!, Diagnostics.A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal);
}
}
else {
return grammarErrorOnNode(node.initializer!, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
}
if (!isConstOrReadonly || isInvalidInitializer) {
return grammarErrorOnNode(node.initializer!, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
}
}
}
function checkGrammarVariableDeclaration(node: VariableDeclaration) {
if (node.parent.parent.kind !== SyntaxKind.ForInStatement && node.parent.parent.kind !== SyntaxKind.ForOfStatement) {
if (node.flags & NodeFlags.Ambient) {
if (node.initializer) {
if (isVarConst(node) && !node.type) {
if (!isStringOrNumberLiteralExpression(node.initializer)) {
return grammarErrorOnNode(node.initializer, Diagnostics.A_const_initializer_in_an_ambient_context_must_be_a_string_or_numeric_literal);
}
}
else {
// Error on equals token which immediate precedes the initializer
const equalsTokenLength = "=".length;
return grammarErrorAtPos(node, node.initializer.pos - equalsTokenLength, equalsTokenLength, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
}
}
if (node.initializer && !(isVarConst(node) && isStringOrNumberLiteralExpression(node.initializer))) {
// Error on equals token which immediate precedes the initializer
const equalsTokenLength = "=".length;
return grammarErrorAtPos(node, node.initializer.pos - equalsTokenLength, equalsTokenLength, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
}
checkAmbientInitializer(node);
}
else if (!node.initializer) {
if (isBindingPattern(node.name) && !isBindingPattern(node.parent)) {
@@ -29632,8 +29634,8 @@ namespace ts {
}
}
if (node.flags & NodeFlags.Ambient && node.initializer) {
return grammarErrorOnFirstToken(node.initializer, Diagnostics.Initializers_are_not_allowed_in_ambient_contexts);
if (node.flags & NodeFlags.Ambient) {
checkAmbientInitializer(node);
}
if (isPropertyDeclaration(node) && node.exclamationToken && (!isClassLike(node.parent) || !node.type || node.initializer ||

View File

@@ -922,6 +922,10 @@ namespace ts {
return !!(getCombinedModifierFlags(node) & ModifierFlags.Const);
}
export function isDeclarationReadonly(declaration: Declaration): boolean {
return !!(getCombinedModifierFlags(declaration) & ModifierFlags.Readonly && !isParameterPropertyDeclaration(declaration));
}
export function isVarConst(node: VariableDeclaration | VariableDeclarationList): boolean {
return !!(getCombinedNodeFlags(node) & NodeFlags.Const);
}

View File

@@ -1,8 +1,8 @@
tests/cases/conformance/ambient/ambientErrors.ts(2,15): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/conformance/ambient/ambientErrors.ts(2,17): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/conformance/ambient/ambientErrors.ts(17,22): error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
tests/cases/conformance/ambient/ambientErrors.ts(20,24): error TS1183: An implementation cannot be declared in ambient contexts.
tests/cases/conformance/ambient/ambientErrors.ts(29,9): error TS1066: In ambient enum declarations member initializer must be constant expression.
tests/cases/conformance/ambient/ambientErrors.ts(34,11): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/conformance/ambient/ambientErrors.ts(34,13): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/conformance/ambient/ambientErrors.ts(35,19): error TS1183: An implementation cannot be declared in ambient contexts.
tests/cases/conformance/ambient/ambientErrors.ts(37,20): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/conformance/ambient/ambientErrors.ts(38,13): error TS1039: Initializers are not allowed in ambient contexts.
@@ -17,7 +17,7 @@ tests/cases/conformance/ambient/ambientErrors.ts(57,5): error TS2309: An export
==== tests/cases/conformance/ambient/ambientErrors.ts (14 errors) ====
// Ambient variable with an initializer
declare var x = 4;
~
~
!!! error TS1039: Initializers are not allowed in ambient contexts.
// Ambient functions with invalid overloads
@@ -57,7 +57,7 @@ tests/cases/conformance/ambient/ambientErrors.ts(57,5): error TS2309: An export
// Ambient module with initializers for values, bodies for functions / classes
declare module M1 {
var x = 3;
~
~
!!! error TS1039: Initializers are not allowed in ambient contexts.
function fn() { }
~

View File

@@ -1,7 +1,7 @@
tests/cases/compiler/ambientErrors1.ts(1,15): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/ambientErrors1.ts(1,17): error TS1039: Initializers are not allowed in ambient contexts.
==== tests/cases/compiler/ambientErrors1.ts (1 errors) ====
declare var x = 4;
~
~
!!! error TS1039: Initializers are not allowed in ambient contexts.

View File

@@ -1,5 +1,5 @@
tests/cases/compiler/ambientStatement1.ts(2,6): error TS1036: Statements are not allowed in ambient contexts.
tests/cases/compiler/ambientStatement1.ts(4,20): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/ambientStatement1.ts(4,22): error TS1039: Initializers are not allowed in ambient contexts.
==== tests/cases/compiler/ambientStatement1.ts (2 errors) ====
@@ -9,6 +9,6 @@ tests/cases/compiler/ambientStatement1.ts(4,20): error TS1039: Initializers are
!!! error TS1036: Statements are not allowed in ambient contexts.
export var v1 = () => false;
~
~~~~~~~~~~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
}

View File

@@ -1,30 +1,30 @@
tests/cases/compiler/constDeclarations-ambient-errors.ts(2,27): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/constDeclarations-ambient-errors.ts(3,26): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/constDeclarations-ambient-errors.ts(2,29): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/constDeclarations-ambient-errors.ts(3,28): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/constDeclarations-ambient-errors.ts(4,20): error TS1254: A 'const' initializer in an ambient context must be a string or numeric literal.
tests/cases/compiler/constDeclarations-ambient-errors.ts(4,37): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/constDeclarations-ambient-errors.ts(4,51): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/constDeclarations-ambient-errors.ts(8,22): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/constDeclarations-ambient-errors.ts(4,39): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/constDeclarations-ambient-errors.ts(4,53): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/constDeclarations-ambient-errors.ts(8,24): error TS1039: Initializers are not allowed in ambient contexts.
==== tests/cases/compiler/constDeclarations-ambient-errors.ts (6 errors) ====
// error: no intialization expected in ambient declarations
declare const c1: boolean = true;
~
~~~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
declare const c2: number = 0;
~
~
!!! error TS1039: Initializers are not allowed in ambient contexts.
declare const c3 = null, c4 :string = "", c5: any = 0;
~~~~
!!! error TS1254: A 'const' initializer in an ambient context must be a string or numeric literal.
~
~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
~
~
!!! error TS1039: Initializers are not allowed in ambient contexts.
declare module M {
const c6 = 0;
const c7: number = 7;
~
~
!!! error TS1039: Initializers are not allowed in ambient contexts.
}

View File

@@ -0,0 +1,24 @@
//// [declarationEmitConstantNoWidening.ts]
export const FOO = 'FOO';
export class Bar {
readonly type = FOO; // Should be widening literal "FOO" - so either `typeof "FOO"` or = "FOO"
}
//// [declarationEmitConstantNoWidening.js]
"use strict";
exports.__esModule = true;
exports.FOO = 'FOO';
var Bar = /** @class */ (function () {
function Bar() {
this.type = exports.FOO; // Should be widening literal "FOO" - so either `typeof "FOO"` or = "FOO"
}
return Bar;
}());
exports.Bar = Bar;
//// [declarationEmitConstantNoWidening.d.ts]
export declare const FOO = "FOO";
export declare class Bar {
readonly type = "FOO";
}

View File

@@ -0,0 +1,11 @@
=== tests/cases/compiler/declarationEmitConstantNoWidening.ts ===
export const FOO = 'FOO';
>FOO : Symbol(FOO, Decl(declarationEmitConstantNoWidening.ts, 0, 12))
export class Bar {
>Bar : Symbol(Bar, Decl(declarationEmitConstantNoWidening.ts, 0, 25))
readonly type = FOO; // Should be widening literal "FOO" - so either `typeof "FOO"` or = "FOO"
>type : Symbol(Bar.type, Decl(declarationEmitConstantNoWidening.ts, 1, 18))
>FOO : Symbol(FOO, Decl(declarationEmitConstantNoWidening.ts, 0, 12))
}

View File

@@ -0,0 +1,12 @@
=== tests/cases/compiler/declarationEmitConstantNoWidening.ts ===
export const FOO = 'FOO';
>FOO : "FOO"
>'FOO' : "FOO"
export class Bar {
>Bar : Bar
readonly type = FOO; // Should be widening literal "FOO" - so either `typeof "FOO"` or = "FOO"
>type : "FOO"
>FOO : "FOO"
}

View File

@@ -1,13 +1,13 @@
tests/cases/compiler/externSemantics.ts(1,14): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/externSemantics.ts(3,21): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/externSemantics.ts(1,15): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/externSemantics.ts(3,22): error TS1039: Initializers are not allowed in ambient contexts.
==== tests/cases/compiler/externSemantics.ts (2 errors) ====
declare var x=10;
~
~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
declare var v;
declare var y:number=3;
~
~
!!! error TS1039: Initializers are not allowed in ambient contexts.

View File

@@ -1,10 +1,10 @@
tests/cases/conformance/externalModules/file1.d.ts(4,9): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/conformance/externalModules/file1.d.ts(5,16): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/conformance/externalModules/file1.d.ts(6,16): error TS1183: An implementation cannot be declared in ambient contexts.
tests/cases/conformance/externalModules/file1.d.ts(11,15): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/conformance/externalModules/file1.d.ts(12,15): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/conformance/externalModules/file1.d.ts(11,17): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/conformance/externalModules/file1.d.ts(12,17): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/conformance/externalModules/file1.d.ts(15,2): error TS1036: Statements are not allowed in ambient contexts.
tests/cases/conformance/externalModules/file1.d.ts(17,16): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/conformance/externalModules/file1.d.ts(17,18): error TS1039: Initializers are not allowed in ambient contexts.
==== tests/cases/conformance/externalModules/file1.d.ts (7 errors) ====
@@ -25,10 +25,10 @@ tests/cases/conformance/externalModules/file1.d.ts(17,16): error TS1039: Initial
}
declare var x = [];
~
~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
declare var y = {};
~
~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
declare module M1 {
@@ -37,6 +37,6 @@ tests/cases/conformance/externalModules/file1.d.ts(17,16): error TS1039: Initial
!!! error TS1036: Statements are not allowed in ambient contexts.
export var v1 = () => false;
~
~~~~~~~~~~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
}

View File

@@ -1,10 +1,10 @@
tests/cases/compiler/missingRequiredDeclare.d.ts(1,1): error TS1046: A 'declare' modifier is required for a top level declaration in a .d.ts file.
tests/cases/compiler/missingRequiredDeclare.d.ts(1,7): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/missingRequiredDeclare.d.ts(1,9): error TS1039: Initializers are not allowed in ambient contexts.
==== tests/cases/compiler/missingRequiredDeclare.d.ts (2 errors) ====
var x = 1;
~~~
!!! error TS1046: A 'declare' modifier is required for a top level declaration in a .d.ts file.
~
~
!!! error TS1039: Initializers are not allowed in ambient contexts.

View File

@@ -1,5 +1,5 @@
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserModifierOnStatementInBlock2.ts(2,4): error TS1184: Modifiers cannot appear here.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserModifierOnStatementInBlock2.ts(2,18): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserModifierOnStatementInBlock2.ts(2,20): error TS1039: Initializers are not allowed in ambient contexts.
==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserModifierOnStatementInBlock2.ts (2 errors) ====
@@ -7,7 +7,7 @@ tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserModifierOnStateme
declare var x = this;
~~~~~~~
!!! error TS1184: Modifiers cannot appear here.
~
~~~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
}

View File

@@ -1,10 +1,10 @@
tests/cases/conformance/parser/ecmascript5/Statements/parserVariableStatement1.d.ts(1,1): error TS1046: A 'declare' modifier is required for a top level declaration in a .d.ts file.
tests/cases/conformance/parser/ecmascript5/Statements/parserVariableStatement1.d.ts(1,7): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/conformance/parser/ecmascript5/Statements/parserVariableStatement1.d.ts(1,9): error TS1039: Initializers are not allowed in ambient contexts.
==== tests/cases/conformance/parser/ecmascript5/Statements/parserVariableStatement1.d.ts (2 errors) ====
var v = 1;
~~~
!!! error TS1046: A 'declare' modifier is required for a top level declaration in a .d.ts file.
~
~
!!! error TS1039: Initializers are not allowed in ambient contexts.

View File

@@ -1,23 +1,23 @@
tests/cases/compiler/varBlock.ts(8,16): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(8,18): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(11,22): error TS2369: A parameter property is only allowed in a constructor implementation.
tests/cases/compiler/varBlock.ts(11,22): error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
tests/cases/compiler/varBlock.ts(15,15): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(21,16): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(22,20): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(25,19): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(26,24): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(26,33): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(27,27): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(28,33): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(28,43): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(32,11): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(33,16): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(33,25): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(34,19): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(35,25): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(35,35): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(15,17): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(21,18): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(22,22): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(25,21): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(26,26): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(26,35): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(27,29): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(28,35): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(28,45): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(32,13): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(33,18): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(33,26): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(34,21): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(35,27): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(35,37): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(39,13): error TS2403: Subsequent variable declarations must have the same type. Variable 'c' must be of type 'any', but here has type 'number'.
tests/cases/compiler/varBlock.ts(39,15): error TS1039: Initializers are not allowed in ambient contexts.
tests/cases/compiler/varBlock.ts(39,17): error TS1039: Initializers are not allowed in ambient contexts.
==== tests/cases/compiler/varBlock.ts (20 errors) ====
@@ -29,7 +29,7 @@ tests/cases/compiler/varBlock.ts(39,15): error TS1039: Initializers are not allo
declare module m3 {
var a, b, c;
var a1, b1 = 10;
~
~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
class C {
@@ -42,7 +42,7 @@ tests/cases/compiler/varBlock.ts(39,15): error TS1039: Initializers are not allo
}
declare var b = 10;
~
~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
declare var a2, b2, c2;
@@ -50,47 +50,47 @@ tests/cases/compiler/varBlock.ts(39,15): error TS1039: Initializers are not allo
declare var da = 10;
~
~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
declare var d3, d4 = 10;
~
~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
module m3 {
declare var d = 10;
~
~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
declare var d2, d3 = 10, d4 = 10;
~
~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
~
~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
export declare var dE = 10;
~
~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
export declare var d2E, d3E = 10, d4E = 10;
~
~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
~
~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
}
declare module m4 {
var d = 10;
~
~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
var d2, d3 = 10, d4 =10;
~
~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
~
~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
export var dE = 10;
~
~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
export var d2E, d3E = 10, d4E = 10;
~
~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
~
~~
!!! error TS1039: Initializers are not allowed in ambient contexts.
}
@@ -98,5 +98,5 @@ tests/cases/compiler/varBlock.ts(39,15): error TS1039: Initializers are not allo
declare var c = 10;
~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'c' must be of type 'any', but here has type 'number'.
~
~~
!!! error TS1039: Initializers are not allowed in ambient contexts.

View File

@@ -0,0 +1,5 @@
// @declaration: true
export const FOO = 'FOO';
export class Bar {
readonly type = FOO; // Should be widening literal "FOO" - so either `typeof "FOO"` or = "FOO"
}