TypeScript继承:扩展属性。

3
“好的,我有两个对象user和participant的简单继承。”
“user”被定义为:

export type userDoc = {
  firstname: string
  lastname: string
  email: string
}

export class User {
  props: userDoc = {
      firstname: "",
      lastname: "",
      email: "", 
      {...}
  }
}

参与者(继承自用户)为:
type participantDoc = {
    pseudonym: string
    karma: number
    impact: number
    level: number
    experience: number
  }

export class Participant extends User {
    props: participantDoc = {
      pseudonym: "",
      karma: 0,
      impact: 0,
      level: 0,
      experience: 0
    }
}

我希望实现的目标是在子类中扩展父类的属性。我正在使用props,因为它更安全地分配,而不是使用Object.assign()。 TypeScript抛出的错误类型:
TS2416: Property 'props' in type 'Participant' is not assignable to thesame property in base type 'User'.
  Type 'participantDoc' is missing the following properties from type 'userDoc': firstname, lastname, email, and 6 more.
2个回答

1
您需要扩展props的类型,就像您为class所做的那样。

更改

export type participantDoc = {
    pseudonym: string
    karma: number
    impact: number
    level: number
    experience: number
}

to

export type participantDoc = {
    pseudonym: string
    karma: number
    impact: number
    level: number
    experience: number
} & userDoc

此外,如果您愿意将类型声明为接口,可以这样做:
export interface userDoc {
  firstname: string
  lastname: string
  email: string
}

export interface participantDoc extends userDoc {
    pseudonym: string
    karma: number
    impact: number
    level: number
    experience: number
}

1
如果User是通用的,以指定其props字段的类型,则继承可以在UserParticipant类之间发挥作用。
另一个提示是依靠常量(当props值为空时)来获取类型。这使得代码更加简洁。
const emptyUserProps = {
    firstname: "",
    lastname: "",
    email: "", 
};

export type UserProps = typeof emptyUserProps;

export class User<TProps extends UserProps = UserProps> {
    props = emptyUserProps as TProps; // Type assertion `as TProps` is needed here in order to initialise the field using `emptyUserProps` (of type `UserProps`, not `TProps`)
}

// -------

const emptyParticipantProps = {
    pseudonym: "",
    karma: 0,
    impact: 0,
    level: 0,
    experience: 0,
};

export type ParticipantProps = typeof emptyParticipantProps;

export class Participant extends User<UserProps & ParticipantProps> {
    props = {
        ...emptyUserProps,
        ...emptyParticipantProps,
    };
}

但是,如果UserParticipant仅在props字段中共享一些数据,则更安全的做法是使用基础接口实现多态,而不是类继承:

export interface WithProps<TProps> {
    props: TProps;
}

// ----

const emptyUserProps = {
    firstname: "",
    lastname: "",
    email: "", 
};

export type UserProps = typeof emptyUserProps;

export class User implements WithProps<UserProps> {
    props = emptyUserProps;
}

// -------

const emptyParticipantProps = {
    pseudonym: "",
    karma: 0,
    impact: 0,
    level: 0,
    experience: 0,
};

export type ParticipantProps = typeof emptyParticipantProps;

export class Participant implements WithProps<UserProps & ParticipantProps> {
    props = {
        ...emptyUserProps,
        ...emptyParticipantProps,
    };
}

另一个选项是使用单个通用类和几个静态工厂方法,其中一个用于创建“基本”用户,另一个用于参与者:
const emptyUserProps = {
    firstname: "",
    lastname: "",
    email: "", 
};

const emptyParticipantProps = {
    pseudonym: "",
    karma: 0,
    impact: 0,
    level: 0,
    experience: 0,
};

export class User<TProps> {
    // `TProps` inferred to `typeof emptyUserProps`
    static createUser(props = emptyUserProps) {
        return new User(props);
    }

    // `TProps` inferred to `(typeof emptyUserProps) & (typeof emptyParticipantProps)`
    static createParticipant(props = {
        ...emptyUserProps,
        ...emptyParticipantProps,
    }) {
        return new User(props);
    }

    private constructor(public props: TProps) {}
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接