对象分配继承不在typescript中工作

问题描述 投票:3回答:2

当我在Angular项目中使用它时代码工作,然后我决定转移到React并且代码工作不正确。

class A {
  constructor(...parts: Partial<A>[]) {
    Object.assign(this, ...parts);
  }
}

class B extends A {
  id: string;
  constructor(...parts: Partial<B>[]) {
    super(...parts);

  }
}

const a = new B({ id: '123' });
console.log(a);

控制台日志的输出是B {id: undefined},我希望它是B {id: '123'}

这是tsconfig:

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": false,
    "allowSyntheticDefaultImports": true,
    "forceConsistentCasingInFileNames": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "preserve",
    "strict": false
  },
  "include": [
    "src"
  ]
}

这是版本:

+ @types/[email protected]
+ [email protected]
+ @types/[email protected]
+ [email protected]
+ @types/[email protected]
+ [email protected]
+ [email protected]
+ @types/[email protected]
+ [email protected]

重现的最小步骤:

  • create-react-app test --typescript
  • 将代码添加到App.tsx
  • 跑,看看控制台

更新:

我最终使用以下解决方案:

class B extends A {
  id: string = this.id;
reactjs typescript
2个回答
2
投票

这是一个known problem。它在TypeScript中不存在。原因是create-react-app TypeScript支持使用TypeScript进行类型检查,使用Babel进行转换。

这个TS代码

class B extends A {
  id: string;
  ...
}

转换为此ES.Next代码:

class B extends A {
  id;
  ...
}

根据class field proposal,未分配的id场转变为this.id = undefined

为了使用符合TypeScript的行为,需要更改设置以使用@babel/plugin-transform-typescript转换为ES5或使用TypeScript而不是Babel,例如弃用react-scripts-ts


0
投票

两种可能的解决方法:

  1. 将Object.assign移动到子类
  2. 创建将返回类实例的工厂:

    export interface Ctor<T> {
        new(...parts: Partial<T>[]): T;
    }

    export class Factory {
        public static Get<T extends object>(ctor: Ctor<T>, ...props: Partial<T>[]): T {
            const res = new ctor();
            Object.assign(res, ...props);
            return res;
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.