Насколько я знаю, вы не можете создавать сопоставленные типы с значениями массива. Как насчет того, чтобы немного изменить подпись, чтобы помочь вам? Вы можете выполнить сопоставленный тип ключей объекта.
type WithParents<T extends Record<string, number>> = {
baseUrl?: string;
name: string;
parents: T;
};
class Resource<T extends Record<string, number>> {
baseUrl?: string;
name: string;
parents: T;
constructor(args: WithParents<T>) {
this.baseUrl = args.baseUrl;
this.name = args.name;
this.parents = args.parents;
}
getBaseUrl(input: { [P in keyof T]: string | number }) {
const parts = Object.keys(this.parents).sort(k => this.parents[k]);
return [this.baseUrl, ...parts.map(key => `${key}/${input[key]}`)]
.filter(Boolean)
.join("/");
}
}
Важными частями здесь являются универсальные шаблоны для класса и типа WithParents
, а также сопоставленный тип arg (на основе аргумент generi c класса) в getBaseUrl
. Вот документы по сопоставленным типам: https://www.typescriptlang.org/docs/handbook/advanced-types.html#mapped -типы
Затем
const x = new Resource({ name: "string", parents: { countries: 1, state: 2 } });
console.log(x.getBaseUrl({ countries: 1, state: 2 })); // countries/1/state/2
console.log(x.getBaseUrl({ state: 1, countries: 2 })); // countries/2/state/1
const y = new Resource({ name: "string", parents: { state: 1, countries: 2 } });
console.log(y.getBaseUrl({ countries: 1, state: 2 })); // state/2/countries/1
console.log(y.getBaseUrl({ state: 1, countries: 2 })); // state/1/countries/2
Вы можете сделать это полезным, например { countries: "number" }
, а затем выполнить некоторую проверку об этом, пока вы там. В его нынешнем виде вы можете указать любое значение для значения записи в записи, и это будет работать.
Изменить: обновлено для поддержания порядка. Поскольку начальные значения для parents
не используются, мы будем использовать их значение для обозначения порядка (начиная с 1).