You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 23:07:08