如果在Typescript中满足一个条件,我如何断言一个联合类型的类型?

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

我有一个对象,可以是这样的。

{ageTop:42}

或者像这样

{locations: [{name:Myrtle Beach}]}

这些对象被作为一个函数的参数传递。(我试图确保函数只得到它能使用的类型,可能有一个这样的,也可能有两个这样的,也可能没有这样的)

我想出的解决方案如下。

我是这样定义接口的。

interface locationsType {
 locations: Array<{name: string}>
}

interface ageTopType {
ageTop: number
}

type keyType = 'ageTop' | 'locations'

我想在我的代码中通过约定来强制执行如果选择lots,我们就使用lotsType接口的事实,我相信这将导致以后有人(或我自己)违反约定时出现错误。我怎样才能通过类型化来强制执行呢?基本上我想创建一些简单的逻辑,如。

 interface traitType {
   key: keyType
   value: this.key === 'locations' ? locationsType : ageTopType;
}

class Developer {
  locations: []
  ageTop;
  constructor(ageTop,locations) {
  this.ageTop = ageTop
  locations.forEach(_val => this.locations.push(_val))
  }
  loadTrait(trait:TraitType) {
    if(trait.key === location) {
      this.trait.value.forEach(_val => this.locations.push(_val)
      return
    }
  this[trait.key] = trait.value;
 }
}

以上已经尝试过了,但并不奏效lol.任何见解?

typescript
2个回答
2
投票

传统的方法是通过一个 歧义会,其中联盟成员有一个共同的。判别式 属性,您可以测试将联合类型的值缩小到其中一个成员。 所以给定

interface LocationsType {
    locations: Array<{ name: string }>
}

interface AgeTopType {
    ageTop: number
}

我们可以定义 TraitType 成为这样的判别联合。

type TraitType = 
  { key: 'ageTop', val: AgeTopType } | 
  { key: 'locations', val: LocationsType };

然后你就可以看到编译器是如何自动使用控制流分析来细化类型的。TraitType 鉴别力测试时。

function foo(t: TraitType) {
    if (t.key === "ageTop") {
        t.val.ageTop.toFixed();
    } else {
        t.val.locations.map(x => x.name.toUpperCase());
    }
}

好的,希望能帮到你,祝你好运!

游戏场链接代码


1
投票

你可以试试类型的联合

interface locationsType {
    locations: Array<{name: string}>;
}

interface ageTopType {
    ageTop: number;
}

type keyType = 'ageTop' | 'locations';

enum traitTypes {
    location = 'locations',
    ageTop = 'ageTop',
}

type traitType = {
    key: traitTypes.location;
    value: Array<locationsType>;
} | {
    key: traitTypes.ageTop;
    value: ageTopType;
};

class Developer {
    public locations: Array<locationsType> = [];
    public ageTop: ageTopType;

    constructor(ageTop: ageTopType, locations: Array<locationsType>) {
        this.ageTop = ageTop;
        this.locations.push(...locations);
    }

    public loadTrait(trait: traitType): void {
        if (trait.key === traitTypes.location) {
            this[trait.key].push(...trait.value);
        } else if (trait.key === traitTypes.ageTop) {
            this[trait.key] = trait.value;
        }
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.