Typescript: --alwaysStrict not ... always strict

Created on 6 Apr 2017  路  7Comments  路  Source: microsoft/TypeScript

TypeScript Version: 2.2.2

Code

In a React Native project:

import React from 'react';

let thing = {a: "first"};
Object.freeze(thing);
thing.a = "second";

tsconfig.json

"compilerOptions":{  
   "target":"es2015",
   "module":"es2015",
   "jsx":"react",
   "outDir":"dist",
   "rootDir":"App",
   "allowSyntheticDefaultImports":true,
   "noImplicitAny":true,
   "strictNullChecks":true,
   "alwaysStrict":true,
   "noUnusedLocals":true,
   "experimentalDecorators":true,
   "preserveConstEnums":true,
   "allowJs":true,
   "moduleResolution":"node",
   "types":[  
      "native-base",
      "redux"
   ],
   "sourceMap":true
},

Expected behavior:
A run-time exception, because alwaysStrict: true.

Actual behavior:
Mutation is silently discarded unless "use strict;" is added to the top of the .ts file.

In #11806 it was identified that "use strict;" is superfluous when module=es2015.

I am using module=es2015 in a React Native and would like "use strict" to be applied to all of my files, but I'm not sure how to do this now. Setting module to commonjs will bring back "use strict" but breaks RN. Setting target=es5 does not enable "use strict";.

Most helpful comment

It looks like the real culprit is the babel preset used in React Native's packager. This can be overrode in .babelrc. This is why RN is not behaving in spec I think.

All 7 comments

Setting target=es5 does not enable "use strict";.

This definitely should work. It is also completely forwards compatible, valid ES2015 to emit a potentially redundant "use strict".

It looks like the real culprit is the babel preset used in React Native's packager. This can be overrode in .babelrc. This is why RN is not behaving in spec I think.

@jeremyjh perhaps, but as you say, tsc emits non strict code using your configuration but under --target es5. That is a problem.

Update:
I've changed my mind about this.

An ES Module aware runtime must ensure that all ES Modules are executed in strict mode if it wants to say that it directly supports ES Module syntax.

SystemJS does just that.
It emits a "use strict" directive prologue in its wrapper for modules in packages with metadata specifying format: "esm".

I'm going to close this; it is not really a Typescript issue, even though Typescript used to support a nice workaround for it. I still actually have not found any workaround other than putting "use strict"; at the top of every module file myself. Building my own .babelrc config with

    ["transform-es2015-modules-commonjs", { strict: true, allowTopLevelThis: true }],

Did not resolve the issue for some reason. But I think its more properly a RN issue.

Perhaps link the issue that you file with React Native.

@aluanhaddad Actually I found they already had one - facebook/react-native#5316 . Basically they can't fix it, too many libraries out there won't compile under strict and all of your project's node_modules will get processed by the packager.

I did get an override to work locally in project, and found I also had a couple of dependencies that don't support strict. So its notations at the top of all my files.

That's frustrating, strict mode should be used in almost every situation, both for security and performance reasons.
Regardless, thank you for linking the issue.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

bgrieder picture bgrieder  路  3Comments

zhuravlikjb picture zhuravlikjb  路  3Comments

Roam-Cooper picture Roam-Cooper  路  3Comments

siddjain picture siddjain  路  3Comments

jbondc picture jbondc  路  3Comments