Reputation: 1596
I'm trying to make something typesafe and I'm not 100% sure if it's possible:
If I have an array of "services", where a Service
is defined as:
interface Service {
id: string;
dependencies?: [string] // refs to others Service.id's
}
Is there a way to make the dependencies
array typesafe? To illustrate:
import { Service } from './service.ts';
const services: Service[] = [
{
id: "authors",
},
{
id: "comments",
}
{
id: "posts",
dependencies: [] // <-- type this as `Array<"authors | "comments">`
}
]
Upvotes: 1
Views: 216
Reputation: 13933
A little bit ugly - to ensure that the id is listed in the array of the dependnecies, you can do the following:
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: [],
}),
]
Upvotes: 0
Reputation: 625
You can use unions to do something like this:
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: [],
}
];
Upvotes: 2