mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-03-15 14:05:47 -05:00
Enable '--strictNullChecks' (#22088)
* Enable '--strictNullChecks' * Fix API baselines * Make sys.getEnvironmentVariable non-nullable * make properties optional instead of using `| undefined` in thier type * reportDiagnostics should be required * Declare firstAccessor as non-nullable * Make `some` a type guard * Fix `getEnvironmentVariable` definition in tests * Pretend transformFlags are always defined * Fix one more use of sys.getEnvironmentVariable * `requiredResponse` accepts undefined, remove assertions * Mark optional properties as optional instead of using `| undefined` * Mark optional properties as optional instead of using ` | undefined` * Remove unnecessary null assertions * Put the bang on the declaration instead of every use * Make `createMapFromTemplate` require a parameter * Mark `EmitResult.emittedFiles` and `EmitResult.sourceMaps` as optional * Plumb through undefined in emitLsit and EmitExpressionList * `ElementAccessExpression.argumentExpression` can not be `undefined` * Add overloads for `writeTokenText` * Make `shouldWriteSeparatingLineTerminator` argument non-nullable * Make `synthesizedNodeStartsOnNewLine` argument required * `PropertyAssignment.initializer` cannot be undefined * Use one `!` at declaration site instead of on every use site * Capture host in a constant and avoid null assertions * Remove few more unused assertions * Update baselines * Use parameter defaults * Update baselines * Fix lint * Make Symbol#valueDeclaration and Symbol#declarations non-optional to reduce assertions * Make Node#symbol and Type#symbol non-optional to reduce assertions * Make `flags` non-nullable to reduce assertions * Convert some asserts to type guards * Make `isNonLocalAlias` a type guard * Add overload for `getSymbolOfNode` for `Declaration` * Some more `getSymbolOfNode` changes * Push undefined suppression into `typeToTypeNodeHelper` * `NodeBuilderContext.tracker` is never `undefined` * use `Debug.assertDefined` * Remove unnecessary tag * Mark `LiteralType.freshType` and `LiteralTupe.regularType` as required
This commit is contained in:
@@ -8,7 +8,7 @@ function endsWith(s: string, suffix: string) {
|
||||
}
|
||||
|
||||
function isStringEnum(declaration: ts.EnumDeclaration) {
|
||||
return declaration.members.length && declaration.members.every(m => m.initializer && m.initializer.kind === ts.SyntaxKind.StringLiteral);
|
||||
return declaration.members.length && declaration.members.every(m => !!m.initializer && m.initializer.kind === ts.SyntaxKind.StringLiteral);
|
||||
}
|
||||
|
||||
class DeclarationsWalker {
|
||||
@@ -30,7 +30,7 @@ class DeclarationsWalker {
|
||||
text += "\ndeclare namespace ts {\n";
|
||||
text += " // these types are empty stubs for types from services and should not be used directly\n"
|
||||
for (const type of walker.removedTypes) {
|
||||
text += ` export type ${type.symbol.name} = never;\n`;
|
||||
text += ` export type ${type.symbol!.name} = never;\n`;
|
||||
}
|
||||
text += "}"
|
||||
}
|
||||
@@ -130,7 +130,7 @@ function writeProtocolFile(outputFile: string, protocolTs: string, typeScriptSer
|
||||
function getInitialDtsFileForProtocol() {
|
||||
const program = ts.createProgram([protocolTs, typeScriptServicesDts], options);
|
||||
|
||||
let protocolDts: string;
|
||||
let protocolDts: string | undefined;
|
||||
program.emit(program.getSourceFile(protocolTs), (file, content) => {
|
||||
if (endsWith(file, ".d.ts")) {
|
||||
protocolDts = content;
|
||||
@@ -162,7 +162,7 @@ function writeProtocolFile(outputFile: string, protocolTs: string, typeScriptSer
|
||||
let protocolDts = getInitialDtsFileForProtocol();
|
||||
const program = getProgramWithProtocolText(protocolDts, /*includeTypeScriptServices*/ true);
|
||||
|
||||
const protocolFile = program.getSourceFile("protocol.d.ts");
|
||||
const protocolFile = program.getSourceFile("protocol.d.ts")!;
|
||||
const extraDeclarations = DeclarationsWalker.getExtraDeclarations(program.getTypeChecker(), protocolFile);
|
||||
if (extraDeclarations) {
|
||||
protocolDts += extraDeclarations;
|
||||
|
||||
@@ -22,7 +22,7 @@ function main(): void {
|
||||
}
|
||||
|
||||
const inputFilePath = sys.args[0].replace(/\\/g, "/");
|
||||
const inputStr = sys.readFile(inputFilePath);
|
||||
const inputStr = sys.readFile(inputFilePath)!;
|
||||
|
||||
const diagnosticMessagesJson: { [key: string]: DiagnosticDetails } = JSON.parse(inputStr);
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ export class Rule extends Lint.Rules.AbstractRule {
|
||||
function walk(ctx: Lint.WalkContext<void>): void {
|
||||
ts.forEachChild(ctx.sourceFile, recur);
|
||||
function recur(node: ts.Node): void {
|
||||
if (node.kind === ts.SyntaxKind.InKeyword && node.parent.kind === ts.SyntaxKind.BinaryExpression) {
|
||||
if (node.kind === ts.SyntaxKind.InKeyword && node.parent!.kind === ts.SyntaxKind.BinaryExpression) {
|
||||
ctx.addFailureAtNode(node, Rule.FAILURE_STRING);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
/**
|
||||
* @license
|
||||
* Copyright 2016 Palantir Technologies, Inc.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import * as ts from "typescript";
|
||||
import * as Lint from "tslint";
|
||||
|
||||
export class Rule extends Lint.Rules.TypedRule {
|
||||
/* tslint:disable:object-literal-sort-keys */
|
||||
public static metadata: Lint.IRuleMetadata = {
|
||||
ruleName: "no-unnecessary-type-assertion",
|
||||
description: "Warns if a type assertion does not change the type of an expression.",
|
||||
options: {
|
||||
type: "list",
|
||||
listType: {
|
||||
type: "array",
|
||||
items: { type: "string" },
|
||||
},
|
||||
},
|
||||
optionsDescription: "A list of whitelisted assertion types to ignore",
|
||||
type: "typescript",
|
||||
hasFix: true,
|
||||
typescriptOnly: true,
|
||||
requiresTypeInfo: true,
|
||||
};
|
||||
/* tslint:enable:object-literal-sort-keys */
|
||||
|
||||
public static FAILURE_STRING = "This assertion is unnecessary since it does not change the type of the expression.";
|
||||
|
||||
public applyWithProgram(sourceFile: ts.SourceFile, program: ts.Program): Lint.RuleFailure[] {
|
||||
return this.applyWithWalker(new Walker(sourceFile, this.ruleName, this.ruleArguments, program.getTypeChecker()));
|
||||
}
|
||||
}
|
||||
|
||||
class Walker extends Lint.AbstractWalker<string[]> {
|
||||
constructor(sourceFile: ts.SourceFile, ruleName: string, options: string[], private readonly checker: ts.TypeChecker) {
|
||||
super(sourceFile, ruleName, options);
|
||||
}
|
||||
|
||||
public walk(sourceFile: ts.SourceFile) {
|
||||
const cb = (node: ts.Node): void => {
|
||||
switch (node.kind) {
|
||||
case ts.SyntaxKind.TypeAssertionExpression:
|
||||
case ts.SyntaxKind.AsExpression:
|
||||
this.verifyCast(node as ts.TypeAssertion | ts.AsExpression);
|
||||
}
|
||||
|
||||
return ts.forEachChild(node, cb);
|
||||
};
|
||||
|
||||
return ts.forEachChild(sourceFile, cb);
|
||||
}
|
||||
|
||||
private verifyCast(node: ts.TypeAssertion | ts.NonNullExpression | ts.AsExpression) {
|
||||
if (ts.isAssertionExpression(node) && this.options.indexOf(node.type.getText(this.sourceFile)) !== -1) {
|
||||
return;
|
||||
}
|
||||
const castType = this.checker.getTypeAtLocation(node);
|
||||
if (castType === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (node.kind !== ts.SyntaxKind.NonNullExpression &&
|
||||
(castType.flags & ts.TypeFlags.Literal ||
|
||||
castType.flags & ts.TypeFlags.Object &&
|
||||
(castType as ts.ObjectType).objectFlags & ts.ObjectFlags.Tuple) ||
|
||||
// Sometimes tuple types don't have ObjectFlags.Tuple set, like when
|
||||
// they're being matched against an inferred type. So, in addition,
|
||||
// check if any properties are numbers, which implies that this is
|
||||
// likely a tuple type.
|
||||
(castType.getProperties().some((symbol) => !isNaN(Number(symbol.name))))) {
|
||||
|
||||
// It's not always safe to remove a cast to a literal type or tuple
|
||||
// type, as those types are sometimes widened without the cast.
|
||||
return;
|
||||
}
|
||||
|
||||
const uncastType = this.checker.getTypeAtLocation(node.expression);
|
||||
if (uncastType === castType) {
|
||||
this.addFailureAtNode(node, Rule.FAILURE_STRING, node.kind === ts.SyntaxKind.TypeAssertionExpression
|
||||
? Lint.Replacement.deleteFromTo(node.getStart(), node.expression.getStart())
|
||||
: Lint.Replacement.deleteFromTo(node.expression.getEnd(), node.getEnd()));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user