TypeScript类嵌套对象初始化问题:运行时未定义错误
问题描述
我正在创建一个包含大量变量的TypeScript类,多数变量可按逻辑分组,希望借助VS Code的自动提示功能提升开发效率。
需求:创建实例const movie1 = new Movie(1, 101);后,输入movie1.时IDE能提示一级属性(如id、title等);输入movie1.title时,提示该嵌套对象的属性(如bg、en、original)。
实际结果
VS Code可正常提供自动提示,但运行脚本时出现以下运行时错误:
this.id.googlesheet.row = rowID; ^ TypeError: Cannot read properties of undefined (reading 'googlesheet') at Movie (~/src/classes/Movie.ts:12:17) at <anonymous> (~/src/index.ts:5:16) at Object.<anonymous> (~/src/index.ts:8:44) at Module._compile (node:internal/modules/cjs/loader:1241:14) at Object.j (~/dist/cjs/index.cjs:1:1197) at Module.load (node:internal/modules/cjs/loader:1091:32) at Module._load (node:internal/modules/cjs/loader:938:12) at cjsLoader (node:internal/modules/esm/translators:283:17) at ModuleWrap.<anonymous> (node:internal/modules/esm/translators:233:7) at ModuleJob.run (node:internal/modules/esm/module_job:217:25)
我认为自己的实现方式存在根本性问题,尝试使用接口但未能解决。
相关代码
src/index.ts
import { Movie } from "./classes/Movie"; const movieList: Movie[] = []; const movie1 = new Movie(1, 101); const movie2 = new Movie(2, 102); console.log(movieList[0].id.googlesheet.row);
src/classes/Movie.ts
export class Movie { id: { googlesheet: { row: number; movie: number; }; wordpress?: { bg?: number; en?: number; }; }; title: { bg: string; en: string; original?: string; }; metadata: { duration: string; yearOfProduction: string; }; country: { bg: string; en: string; }; description: { bg: string; en: string; }; director: { bg: string; en: string; }; trailer: { url: string; }; featuredImage: { url: string; }; constructor(rowID: number, movieID: number) { this.id.googlesheet.row = rowID; this.id.googlesheet.movie = movieID; } }
解决方案
核心问题是你只给类属性声明了类型,但未在构造函数中初始化嵌套对象,导致this.id初始值为undefined,自然无法访问其下的googlesheet属性。
方法1:构造函数内直接初始化嵌套结构
先创建完整的嵌套对象结构,再赋值具体数据:
export class Movie { id: { googlesheet: { row: number; movie: number; }; wordpress?: { bg?: number; en?: number; }; }; title: { bg: string; en: string; original?: string; }; metadata: { duration: string; yearOfProduction: string; }; country: { bg: string; en: string; }; description: { bg: string; en: string; }; director: { bg: string; en: string; }; trailer: { url: string; }; featuredImage: { url: string; }; constructor(rowID: number, movieID: number) { // 先初始化id的嵌套结构 this.id = { googlesheet: { row: rowID, movie: movieID } }; // 其他属性也需初始化,避免后续访问报错 this.title = { bg: '', en: '' }; this.metadata = { duration: '', yearOfProduction: '' }; this.country = { bg: '', en: '' }; this.description = { bg: '', en: '' }; this.director = { bg: '', en: '' }; this.trailer = { url: '' }; this.featuredImage = { url: '' }; } }
方法2:用接口拆分类型,提升可读性
把嵌套结构抽成独立接口,让类型定义更清晰,同时完成初始化:
// 拆分嵌套接口 interface GoogleSheetID { row: number; movie: number; } interface WordPressID { bg?: number; en?: number; } interface MovieID { googlesheet: GoogleSheetID; wordpress?: WordPressID; } interface LocalizedText { bg: string; en: string; original?: string; } export class Movie { id: MovieID; title: LocalizedText; metadata: { duration: string; yearOfProduction: string; }; country: LocalizedText; description: LocalizedText; director: LocalizedText; trailer: { url: string; }; featuredImage: { url: string; }; constructor(rowID: number, movieID: number) { this.id = { googlesheet: { row: rowID, movie: movieID } }; // 初始化其他属性 this.title = { bg: '', en: '' }; this.metadata = { duration: '', yearOfProduction: '' }; this.country = { bg: '', en: '' }; this.description = { bg: '', en: '' }; this.director = { bg: '', en: '' }; this.trailer = { url: '' }; this.featuredImage = { url: '' }; } }
额外修正
你的index.ts中还有一个问题:movieList是空数组,直接访问movieList[0]会得到undefined,需先将实例添加到数组:
import { Movie } from "./classes/Movie"; const movieList: Movie[] = []; const movie1 = new Movie(1, 101); const movie2 = new Movie(2, 102); // 将实例加入数组 movieList.push(movie1, movie2); console.log(movieList[0].id.googlesheet.row); // 正常输出1
内容的提问来源于stack exchange,提问作者Gabriel Atanasov
相关产品推荐
相关产品推荐

