export type IsInArray = X extends A[number]
? true
: false;
export type HasUniqueItems = A extends readonly [
infer X,
...infer Rest,
]
? IsInArray extends true
? [false, "Encountered value with duplicates:", X]
: HasUniqueItems
: true;
type TyEnum = {
[Key in K]: Key;
};
type TyStrToInd = {
[Key in K]: number;
};
type TyCoolEnum> = {
asArr: Tuple;
asObjEnum: Readonly>;
asSet: Set;
asStrToInd: Readonly>;
};
// generate type-safe object (as enum) from array of strings
export const createCoolEnum = <
// prettier-ignore
TupleInput extends (
number extends TupleInput["length"] ? `Should be as const` :
HasUniqueItems> extends true ? Readonly :
`Should have unique elements, found duplicate`
),
Tuple extends Exclude,
>(
arrInput: TupleInput,
): TyCoolEnum => {
const arr = arrInput as unknown as Tuple;
const asSet = new Set(arr);
if (asSet.size !== arr.length) {
throw new Error("groupIdsArr should have unique elements");
}
type TheObjEnum = TyEnum;
const asObjEnum: TheObjEnum = arr.reduce((accu, curr) => {
accu[curr] = curr;
return accu;
}, {} as Record) as TheObjEnum;
type TheStrToInd = TyStrToInd;
const asStrToInd: TheStrToInd = arr.reduce((accu, curr, index) => {
accu[curr] = index;
return accu;
}, {} as Record) as TheStrToInd;
const final: TyCoolEnum = {
asArr: arr,
asObjEnum,
asSet,
asStrToInd,
};
return final;
};
// test:
// let jijdfdf = ["vbvvbvbbvb", "qeqeqeqe", "i7777", "i7777"] as const;
// const qqdqd = createCoolEnum(jijdfdf);
// const qqdqd2 = createCoolEnum(["dfdf", "bbbbb"]);
// qqdqd.asObjEnum.i7777;
// qqdqd2.asObjEnum.dfdf;