繁体   English   中英

从另一个 Propertyin Typescript 推断类型?

[英]infer type From another Propertyin Typescript?

我一直在这里和那里撞到我的头,我无法获得比这更多的进步

例如,我希望 TObject.props 仅在我传递TObject.name = 'a'时才接受'href''download'而不是 If passed TObject.name = 'p'

以及如何让 reduxStoreType.objects 接受一个 TObjects 数组,但不一定所有的 TObjects 都应该是一种类型,如 Tobjects<'a'>

例如我希望有以下可能性

reduxStoreType.objects = [TObject<'a'>,TObject<'p'>,TObject<'div'>...]

这是我的界面

interface TagsTypes {
  // HTML
  p: React.HTMLAttributes<HTMLParagraphElement>;
  a: React.AnchorHTMLAttributes<HTMLAnchorElement>;
  form: React.FormHTMLAttributes<HTMLFormElement>;
  head: React.HTMLAttributes<HTMLHeadElement>;
  img: React.ImgHTMLAttributes<HTMLImageElement>;
  input: React.InputHTMLAttributes<HTMLInputElement>;
  span: React.HTMLAttributes<HTMLSpanElement>;
  button: React.ButtonHTMLAttributes<HTMLButtonElement>;
  div: React.HTMLAttributes<HTMLDivElement>;
}

interface TObject<T extends keyof TagsTypes> {
  width: number;
  height: number;
  name:  T;
  props: TagsTypes[T];
  innerText: string;
}

interface CanvasType extends HTMLDivElement {}

interface reduxStoreType {
  canvas: CanvasType;
  objects: TObject<'a'>;
}

让我们将您的问题简化为更简单的问题,解决更简单的版本,然后希望您可以将其应用到您的真实场景中。

我们有一些形状:

type ShapeTypes = "circle" | "square" | "rectangle" | "triangle";

我们可以这样表达对象(类似于您当前的 TObject 定义):

interface Shape<Type extends ShapeTypes> {
    type: Type;
    area: number;
}

但这就是问题所在。 如果我们想要一个圆有半径或直径怎么办? 正方形有边长? 三角形的分类?

这是我们使用可区分联合的地方:

type Shape =
    {
        type: "circle";
        area: number;
        radius: number;
    } | {
        type: "square";
        area: number;
        side: number;
    } | { ... }; // more

正如您现在看到的,每种类型的形状都具有特定于它们的属性。 虽然这需要输入更多内容,但这正是您想要的。 你会看到我们何时像这样使用它们:

if (shape.type === "circle") {
    shape.radius // number, no errors
    shape.side   // error! 
} else if (shape.type === "square") {
    shape.radius // error!
    shape.side   // number, no errors
} else if (...) { ... } // more if you want

而且在数组中使用它们就像Shape[]一样简单,同时仍然保留所有这些类型信息。

如果键入所有冗余共享属性太长,请创建一个新的基本类型并将其与联合中的每个成员相交:

type Base = {
    area: number;
    // more properties if needed
};

type Shape = 
    {
        type: "circle";
        radius: number;
    } & Base | {
        // ...
    } | { ... }; // others

那么现在你如何将它应用到你的案例中呢?

下面是一些入门代码:

type TBaseObject = {
    // ...
};

type TObject = {
    // ...
} | {
    // ...
}; // ...

interface reduxStoreType {
  canvas: CanvasType;
  objects: TObject[];
}

暂无
暂无

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

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