简体   繁体   English

在typescript中正确添加一个class的实例

[英]Correctly add instance of a class in typescript

I have 3 class objects A, B, C. I have a property in class B called handleDropDown().我有 3 个 class 对象 A、B、C。我在 class B 中有一个名为 handleDropDown() 的属性。

I have created a custom type我创建了一个自定义类型

type PageObject = { pageObject: A |输入 PageObject = { pageObject: A | B |乙 | C; C; } }

It can either be class A,B or C.它可以是 class A、B 或 C。

When try to access the handleDropDown from class BI get an error that当尝试从 class BI 访问 handleDropDown 时出现错误

Property 'handleDropDown' does not exist on type 'A |类型“A | 上不存在属性“handleDropDown” B |乙 | C'. C'。

I am new to typescript was wondering what I am doing wrong我是 typescript 的新手,想知道我做错了什么

 type Query = { name: string; } class BaseAll { } class BaseInfo { } class A extends BaseAll { query: Query; constructor(query: Query) { super(); this.query = query; } } class B extends BaseAll { query: Query; constructor(query: Query) { super(); this.query = query; } handleDropDown() { console.log('I am here') } } class C extends BaseAll { query: Query; constructor(query: Query) { super(); this.query = query; } } type PageObject = { pageObject: A | B | C; } class Page { header: string; objs: { [key: string]: A | B | C } = {}; constructor(text: string) { this.header = text; } setHeaderText(text: string) { return text } addObj(name: string, obj: A | B | C) { this.objs[name] = obj; } } let myQuery3 = { name: 'list' }; let myQuery2 = { name: 'file' }; let A1 = new A(myQuery3); let A2 = new A(myQuery2); let C1 = new C(myQuery2); let C2 = new C(myQuery3); let page1 = new Page("Page title Here"); page1.addObj('t1', A1); page1.addObj('t2', A2); page1.addObj('f1', C1); page1.addObj('f2', C2); console.log(page1.objs.t1.query); console.log(page1.objs.t2.query); console.log(page1.objs.f1.handleDropDown()); console.log(page1.objs.f2.handleDropDown()); //let page1_filter = new Filter("Dashboard", [],[]); // page1.updateQuery(myQuery2); console.log(page1);

While a runtime check via instanceof B is always an option, I would consider using an const object literal.虽然通过instanceof B进行运行时检查始终是一个选项,但我会考虑使用 const object 文字。

When dealing with const object literals, TS can infer precise type of that object.在处理 const object 文字时,TS 可以推断出该 object 的精确类型。

interface Page {
  header: string;
  objs: {
    [key: string]: A | B | C;
  }
};

const A1 = new A(myQuery3);
const A2 = new A(myQuery2);
const B1 = new B(myQuery2);
const C2 = new C(myQuery3);

const page1 = {
  header: 'Page title Here',
  objs: {
    t1: A1,
    t2: A2,
    f1: B1,
    f2: C2
  }
} satisfies Page;
console.log(page1.objs.t1.query);
console.log(page1.objs.t2.query);
console.log(page1.objs.f1.handleDropDown());
console.log(page1.objs.f2.handleDropDown());  // Expected error

Please note that:请注意:

  • inferred type if page1 is:推断类型,如果 page1 是:
const page1: {
    header: string;
    objs: {
        t1: A;
        t2: A;
        f1: B;
        f2: C;
    };
}
  • this code uncovers a bug in your code (in compile time) - you are trying to call handleDropDown on f1 and f2 of type C - which do not have these methods.这段代码揭示了代码中的一个错误(在编译时)——你试图在类型为Cf1f2上调用handleDropDown它们没有这些方法。 This is an advantage over runtime check.这是优于运行时检查的优势。
  • I used TS 4.9 satisfies operator to still have type checking and code completion我使用 TS 4.9 满足运算符仍然具有类型检查和代码完成

Playground link 游乐场链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM