how would i runtime typecheck an interface with dynamic keys?

my initial attempt was something like this
crates: t.interface({
[t.string]: t.interface({
id: t.string,
uid: t.string,
}),
}),
crates: t.interface({
[t.string]: t.interface({
id: t.string,
uid: t.string,
}),
}),
16 Replies
PepeElToro41
PepeElToro4110mo ago
t.map
Ohirume
OhirumeOP10mo ago
uh where? here are my types
crates: CratesState;
crates: CratesState;
export interface CratesState {
readonly [uid: string]: CrateEntity | undefined;
}
export interface CratesState {
readonly [uid: string]: CrateEntity | undefined;
}
export interface CrateEntity {
readonly id: string;
readonly uid: string;
}
export interface CrateEntity {
readonly id: string;
readonly uid: string;
}
PepeElToro41
PepeElToro4110mo ago
crates: t.map(t.string, t.interface({
id: t.string,
uid: t.string,
}))
crates: t.map(t.string, t.interface({
id: t.string,
uid: t.string,
}))
Ohirume
OhirumeOP10mo ago
hmm thanks!
PepeElToro41
PepeElToro4110mo ago
the type would be as Map though
Ohirume
OhirumeOP10mo ago
is there a way for t to infer from just the types?
PepeElToro41
PepeElToro4110mo ago
which might not be ideal you'd need to typecast it not really, flamework has a transformer for it if it works good enough sure
Ohirume
OhirumeOP10mo ago
would crates state be a map? is there like a difference between CratesState and Map<string, CratesEntity>
PepeElToro41
PepeElToro4110mo ago
yes, usually for those types it's better to use a map when compiled it compiles to the same table
Ohirume
OhirumeOP10mo ago
export const crateCheck: t.check<CrateEntity> = t.interface({
id: t.string,
uid: t.string,
});

export const cratesCheck = t.map(t.string, crateCheck) as unknown as t.check<CratesState>;
export const crateCheck: t.check<CrateEntity> = t.interface({
id: t.string,
uid: t.string,
});

export const cratesCheck = t.map(t.string, crateCheck) as unknown as t.check<CratesState>;
i feel like im being forceful here whats the better approach
PepeElToro41
PepeElToro4110mo ago
maybe you can create an util function that just uses map and returns an interface-like or directly use a map, but it might have some disadvantages
Ohirume
OhirumeOP10mo ago
on the types? or checks so like just use maps for my types?
PepeElToro41
PepeElToro4110mo ago
the function would just use map, but it would cast to a { [K]: V } so you dont need to do as unknown as everytime
Ohirume
OhirumeOP10mo ago
what does the function work with, the actual data? or the checks sorry, im pretty new to these concepts
PepeElToro41
PepeElToro4110mo ago
export function checkInterface<K extends keyof any, T>(key: t.check<K>, value: t.check<T>) {
return t.map(key, value) as unknown as t.check<{[TK in K]: T}>
}
export function checkInterface<K extends keyof any, T>(key: t.check<K>, value: t.check<T>) {
return t.map(key, value) as unknown as t.check<{[TK in K]: T}>
}
Ohirume
OhirumeOP10mo ago
oh so just do the as unknown as inside the util function alright thanks!

Did you find this page helpful?