为何构造函数中定义对象后,TypeScript仍提示‘对象可能未定义’?
问题解答
1. TypeScript提示this.authService可能未定义的原因
你开启了TypeScript的strictPropertyInitialization严格模式(属于strict总开关的一部分),该规则要求类的所有属性必须在声明时初始化,或者在构造函数中完成初始化。
虽然你在构造函数里给this.authService赋了值,但属性声明authService: AuthService;没有标记为肯定会被初始化,TypeScript的静态分析无法完全确保这个属性一定有值(极端场景如基类构造函数抛出异常,导致子类后续赋值代码不执行,但这种情况几乎不会出现),因此会抛出TS2532错误。
2. 为什么要先创建常量再传入super
在JavaScript/TypeScript的子类构造函数中,必须先调用super()才能访问this,这是语法强制规则。你需要把AuthService实例同时传给基类(通过super参数)和赋值给子类的this.authService,就只能先把实例存成局部常量,先传给super,等super执行完成后,再将这个常量赋值给this.authService——毕竟在super之前根本无法使用this,没法直接先给this.authService赋值再传给super。
解决方法
有两种方式可以消除TS报错:
方式一:在属性声明时添加肯定赋值断言(
!)
明确告诉TypeScript该属性一定会被初始化,无需再做检查:export class AuthController extends CrudController<any> { authService!: AuthService; // 添加!标记 constructor(app: Express) { const authService = new AuthService(database.db!); super('auth', app, authService); this.authService = authService; } registerUser(req: Request, res: Response, next: NextFunction) { this.authService.createUser(orgId, req.body) .then((doc) => { return res.status(201).json(doc); }) } }方式二:利用参数属性语法简化初始化
直接将构造函数参数转为类属性,同时完成初始化,省略单独的属性声明和赋值步骤:export class AuthController extends CrudController<any> { constructor(app: Express, private authService: AuthService = new AuthService(database.db!)) { super('auth', app, authService); } registerUser(req: Request, res: Response, next: NextFunction) { this.authService.createUser(orgId, req.body) .then((doc) => { return res.status(201).json(doc); }) } }
内容的提问来源于stack exchange,提问作者Tim Hardy
相关产品推荐
相关产品推荐

