tsconfig.json strict属性配置false会有什么响

当你在 tsconfig.json 中将 "strict": false 时,TypeScript 会关闭一组"严格类型检查"规则。这样虽然可以更快上手、减少编译报错,但也会让更多潜在的运行时错误躲过编译期,降低代码可维护性和重构安全性。

下面先解释 strict 的概念与包含的子选项,再通过通俗示例展示关闭 strict 可能带来的问题,以及相应的"正确写法"。

strict 是什么?

在 TypeScript 中,"strict": true 会一次性启用一组严格相关的检查选项(具体集合随 TS 版本略有变化,一般包括):

  • "noImplicitAny":禁止隐式的 any
  • "strictNullChecks":严格区分可能为 null/undefined 的值。
  • "strictFunctionTypes":更严格地检查函数类型参数的协变/逆变。
  • "strictBindCallApply":严格检查 call/apply/bind 的参数类型。
  • "strictPropertyInitialization":类的实例属性必须初始化或在构造函数中赋值。
  • "useUnknownInCatchVariables"catch (e) 中的 e 默认为 unknown,需要显式缩小或断言。
  • "noImplicitThis":禁止隐式的 this:any
  • "alwaysStrict":编译后的 JS 使用严格模式("use strict"),非模块脚本场景更明显。

注意:

  • 有些常用但不在 strict 集合内的"更严"选项(如 "noUncheckedIndexedAccess""exactOptionalPropertyTypes")需要手动单独开启。
  • 严格集合可能随 TS 版本演进略有增减,以本地 TypeScript 版本文档为准。

关闭 strict 的总体影响

  • 更多隐式的 any 混入,类型信息丢失,重构风险上升。
  • null/undefined 不再被严格检查,出现空指针类错误的概率增加。
  • 函数的参数与回调更容易"误配",问题延迟到运行时才爆炸。
  • 类的属性可能未初始化即被访问,导致不可预期的 undefined
  • catch (e) 直接当成 any 使用,降低异常处理的安全性与可读性。
  • 运行时严格模式的约束(在非模块脚本里)可能缺失,某些 this 绑定问题更隐蔽。

常见场景与示例

以下示例中的"错误示例"指的是:strict 关闭时能编译通过、但存在潜在运行时风险或类型不安全;"正确示例"是符合 strict 的写法或修复方式。

1、noImplicitAny:隐式 any

错误示例(strict 关闭时编译通过,风险大):

sql 复制代码
function add(a, b) {
  // a 和 b 被推断为 any,"数字相加"变成了"任意拼接"
  return a + b;
}

add(1, "2"); // 运行结果是 "12",并非 3

正确示例(显式标注或提供默认值/约束):

less 复制代码
function add(a: number, b: number) {
  return a + b;
}

add(1, 2); // 3

参考:

2、strictNullChecks:空值检查

  • 作用:将 null、undefined 从所有类型中分离出来,必须显式处理"可能为空"的情况。
  • 影响:开启后可显著减少空指针错误,但需要在代码中做空值校验或使用可选链等。

错误示例

typescript 复制代码
function greet(name: string) {
  // 如果实际传的是 undefined,这里会在运行时报错
  console.log(name.toUpperCase());
}

greet(undefined as any); // 运行期 TypeError

正确示例(显式包含可能的空值并做保护):

javascript 复制代码
function greet(name: string | undefined) {
  if (!name) {
    console.log("Hello, stranger!");
    return;
  }
  console.log(name.toUpperCase());
}

或改为不允许空值

scss 复制代码
function greet(name: string) {
  console.log(name.toUpperCase());
}

// 调用方自己保证非空
greet("Alice");

参考:

3、 strictPropertyInitialization:属性初始化

错误示例(strict 关闭时编译通过,但属性为 undefined):

typescript 复制代码
class User {
  name: string; // 未初始化
  constructor() {
    // 忘了给 name 赋值
  }
}

const u = new User();
u.name.toUpperCase(); // 运行期 TypeError

正确示例(在声明处或构造函数中初始化,或使用确定赋值断言):

typescript 复制代码
// 方式一:声明处初始化
class User {
  name: string = "anonymous";
}

// 方式二:构造函数中初始化
class User2 {
  name: string;
  constructor(name: string) {
    this.name = name;
  }
}

// 方式三:确定赋值断言(慎用,需要你自己保证在使用前已赋值)
class User3 {
  name!: string;
  init(name: string) {
    this.name = name;
  }
}

参考:

www.typescriptlang.org/tsconfig/#s...

4、strictBindCallApply:call/apply 的参数检查

错误示例(strict 关闭时编译通过,运行期可能异常):

typescript 复制代码
function sum(a: number, b: number): number {
  return a + b;
}

sum.call(null, 1, "2" as any); // 编译不报错,但语义错误

正确示例(严格匹配参数类型):

typescript 复制代码
function sum(a: number, b: number): number {
  return a + b;
}

sum.call(null, 1, 2); // OK

参考:

www.typescriptlang.org/tsconfig/#s...

5、strictFunctionTypes:函数类型的参数检查更严格

错误示例(strict 关闭时可能被接受,存在类型不安全):

typescript 复制代码
interface Animal { name: string }
interface Dog extends Animal { bark(): void }

type Handler = (a: Animal) => void;

// 将参数更"窄"的函数赋给更"宽"的函数类型(不安全)
const handleDog: (d: Dog) => void = d => d.bark();

// 在 strictFunctionTypes 关闭时,这样的赋值可能被允许
const h: Handler = handleDog;

// 运行时:如果传入的是普通 Animal 而非 Dog,会出错
const justAnimal: Animal = { name: "Tom" };
h(justAnimal as any); // 运行期可能调用 bark() 报错

正确示例(使用恰当的参数范围或做类型保护):

javascript 复制代码
const handleAnimal: Handler = a => {
  // 若需要 Dog 的行为,先做类型缩小
  if ((a as Dog).bark) {
    (a as Dog).bark();
  } else {
    console.log(a.name);
  }
};

或改变设计:将"输出协变、输入逆变"的原则体现到类型中,避免将"窄参数函数"赋给"宽参数函数"。

参考:

www.typescriptlang.org/tsconfig/#s...

6、useUnknownInCatchVariables:异常类型安全

错误示例(strict 关闭时 e 是 any,使用随意):

javascript 复制代码
try {
  throw new Error("oops");
} catch (e) {
  // e 是 any,随意访问属性,潜在不安全
  console.log(e.message.toUpperCase());
}

正确示例(将 e 视为 unknown,先缩小/断言):

javascript 复制代码
try {
  throw new Error("oops");
} catch (e) {
  if (e instanceof Error) {
    console.log(e.message.toUpperCase());
  } else {
    console.log("Unknown error", e);
  }
}

参考:

www.typescriptlang.org/tsconfig/#u...

7、noImplicitThis:避免 this:any

错误示例(strict 关闭时不报错,运行期 this 可能是 undefined 或全局对象):

javascript 复制代码
function getX() {
  // 在非严格模式下,独立调用时 this 可能指向全局;在严格模式下为 undefined
  return (this as any).x;
}

const obj = { x: 42, getX };
const fn = obj.getX;

console.log(fn()); // 结果依赖调用环境,容易出错

正确示例(显式 this 类型或用箭头函数绑定):

javascript 复制代码
function getX(this: { x: number }) {
  return this.x;
}

const obj = { x: 42, getX };
console.log(obj.getX()); // 42

或者:

ini 复制代码
const obj2 = {
  x: 42,
  getX: () => 42, // 不依赖 this
};

参考:

www.typescriptlang.org/tsconfig/#n...

8、alwaysStrict:输出严格模式

在非模块脚本中,关闭 strict 也可能意味着编译产物不含 "use strict"。这会影响诸如 this 的指向、静默失败等行为,增加与运行时相关的隐患。使用模块(ESM/CJS)时通常天然是严格模式,但仍建议开启 alwaysStrict 以保持一致性。

什么时候可以考虑关掉 strict?

  • 原有 JavaScript/TS 项目体量大、类型债务多,短期无法一次性治理。
  • 第三方声明文件质量参差、阻塞开发进度时,临时"松绑"。

即便如此,也建议:

  • 尽量只临时关闭,或仅关闭阻塞你当前工作的个别子选项,而不是整个 "strict": false
  • 在关键模块、核心域模型里保持严格。
  • 逐步还债:为公共 API、数据边界(网络、存储、DOM)补上类型。

渐进式启用的建议

  • 打开 "strict": true,如果报错太多,逐个关闭必要的子选项,再计划性回收:

    • 先解决 "noImplicitAny""strictNullChecks"(收益最大)。
    • 再处理 "strictPropertyInitialization""noImplicitThis" 等。
  • 配合 ESLint(typescript-eslint)规则,保持一致的代码风格与安全约束。

  • 在项目中引入额外的安全选项(即便不在 strict 内):

    • "noUncheckedIndexedAccess": true(索引访问返回 T | undefined
    • "exactOptionalPropertyTypes": true(可选属性更精确)
  • 对外部输入做运行时校验(zod、io-ts),让类型安全与数据校验形成闭环。

总结

  • 关闭 "strict" 会让 TypeScript 更宽松、上手更快,但潜在运行时错误更容易漏网,重构成本和风险上升。
  • 严格模式能在"写代码"而不是"跑起来"时暴露问题,长期能显著提升代码质量与信心。
  • 如果历史原因不得不开启宽松模式,也应规划渐进式回到严格,至少保证关键路径与公共接口的类型安全。
相关推荐
Danny_FD1 小时前
Vue2 + Node.js 快速实现带心跳检测与自动重连的 WebSocket 案例
前端
uhakadotcom1 小时前
将next.js的分享到twitter.com之中时,如何更新分享卡片上的图片?
前端·javascript·面试
韦小勇1 小时前
el-table 父子数据层级嵌套表格
前端
奔赴_向往1 小时前
为什么 PWA 至今没能「掘进」主流?
前端
小小愿望1 小时前
微信小程序开发实战:图片转 Base64 全解析
前端·微信小程序
掘金安东尼1 小时前
2分钟创建一个“不依赖任何外部库”的粒子动画背景
前端·面试·canvas
电商API大数据接口开发Cris1 小时前
基于 Flink 的淘宝实时数据管道设计:商品详情流式处理与异构存储
前端·数据挖掘·api
小小愿望1 小时前
解锁前端新技能:让JavaScript与CSS变量共舞
前端·javascript·css
程序员鱼皮1 小时前
爆肝2月,我的 AI 代码生成平台上线了!
java·前端·编程·软件开发·项目
天生我材必有用_吴用1 小时前
一文搞懂 useDark:Vue 项目中实现深色模式的正确姿势
前端·vue.js