typescript 如何描述类型,以便当输入某个键时,允许另一个键

hgqdbh6s  于 2023-05-08  发布在  TypeScript
关注(0)|答案(1)|浏览(158)

对不起,我的英语,你能告诉我如何描述类型,以便当一个特定的关键是输入,另一个关键是允许输入?

interface Base {
  top?: number;
  left?: number;
  behavior?: "auto" | "smooth"
}

interface OffsetTopProps {
  offsetTop?: number;
}

interface OffsetLeftProps {
  offsetLeft?: number;
}

// in case when top was filled, we can enter offsetTop?: number; similarly with left

我试过和工会合作,但没用。

type test = Base | OffsetTopProps | OffsetLeftProps
eh57zj3b

eh57zj3b1#

如果你想在top不存在的时候强制执行,那么offsetTop也必须不存在,那么你可以像这样将类型的这一部分表示为一个联合:

type Top = 
  { top: number, offsetTop?: number } | 
  { top?: never, offsetTop?: never };

TypeScript并没有直接的方法来禁止对象类型中的属性键,但是你可以说这个键是一个可选的属性,它的值是不可能的never类型。由于没有never类型的值,因此您可以做的唯一合理的事情就是将属性忽略(或者将其设置为undefined)。因此,Top要么有一个number类型的top属性和一个number类型的可选offsetProperty,要么既没有top也没有offsetTop属性。
类似地,对于left/offsetLeft对:

type Left = 
  { left: number, offsetLeft?: number } | 
  { left?: never, offsetLeft?: never };

现在你可以将它们与Base组合得到Test

interface Base {
  behavior?: "auto" | "smooth"
}

type Test = Base & Top & Left;

由于TestBaseTopLeft的交集,因此Test类型的值必须符合所有三个定义。
让我们测试一下:

let t: Test;    
t = { behavior: "auto", top: 1 }; //okay
t = { top: 1, offsetTop: 2 }; // okay
t = { top: 1, offsetTop: 2, left: 3 }; // okay
t = { top: 1, offsetTop: 2, left: 3, offsetLeft: 4 }; // okay
t = { left: 3 }; // okay
t = { left: 3, offsetLeft: 4 }; // okay

t = { offsetTop: 2 }; // error
t = { offsetLeft: 4 }; // error
t = { top: 1, offsetTop: 2, offsetLeft: 4 }; // error

编译器允许有效值,但拒绝包含offsetTop但没有topoffsetLeft但没有left的无效值。
Playground链接到代码

相关问题