打字稿:收集对象数组属性的所有字符串文字

时间:2020-10-24 08:22:48

标签: typescript

我正在尝试使类型安全,但我不确定100%是否可行:

如果我有一个“服务”数组,其中Service定义为:

interface Service {
  id: string;
  dependencies?: [string] // refs to others Service.id's
}

是否可以使dependencies数组类型安全?为了说明:

import { Service } from './service.ts';

const services: Service[] = [
  {
    id: "authors",
  },
  {
    id: "comments",
  }
  {
    id: "posts",
    dependencies: [] // <-- type this as `Array<"authors | "comments">`
  }
]

2 个答案:

答案 0 :(得分:2)

您可以使用unions做这样的事情:

type RawType = "authors" | "comments";
type RawId = { id : RawType };
type Posts = {
  id: "posts";
  dependencies: RawType[];
}

type Service = RawId | Posts;

// then you can declare an array of Service
const services: Service[] = [
  {
    id: "authors",
  },
  {
    id: "comments",
  },
  {
    id: "posts",
    dependencies: [],
  }
];

Playground

答案 1 :(得分:0)

有点丑陋-要确保ID在相关性数组中列出,您可以执行以下操作:

type Id = 'id1' | 'id2' | 'id3'
type Obj<CurrentId extends Id> = {
  id: CurrentId
  dependencies: Exclude<Id, CurrentId>[]
}

const obj: <CurrentId extends Id>(obj: Obj<CurrentId>) => Obj<CurrentId> = obj => obj

const array = [
  obj({
    id: 'id1',
    dependencies: [], // compiled
  }),
  obj({
    id: 'id2',
    dependencies: ['id1'], // compiled
  }),
  obj({
    id: 'id3',
    dependencies: ['id3'], // compilation error
  }),
  obj({
    id: 'id3', // note: compiled even when there are multiple objects with the same Id
    dependencies: [],
  }),
]