Home > database >  is there any way I can set the type as one of array element in a function parameters?
is there any way I can set the type as one of array element in a function parameters?

Time:03-21

// This is what I tried, but did not work

function useAccordion<T extends Readonly<Array<string>>>(keys:T,defaultOpenKey: T[number]){
    // ...
}

useAccordion(["panel1","panel2","panel3"], "panel1") // 2nd argument has to be one of the element from the keys(first argument)

useAccordion(["panel1","panel2","panel3"], "panel7") // It should throw a typescript error 

note: as const type assertion works but can't figure out how to set the type assertion in the function argument. e.g.

const KEYS = [
  "panel1","panel2","panel3"
] as const

const initialOpen:typeof KEYS[number] = "panel1" // correct
const initialOpen:typeof KEYS[number] = "panel8"  // Error

The question is how can I do the same thing inside a function args.

Thanks

CodePudding user response:

You can pass your type KEYS into the generic of useAccordion which will help you to correct types on that function's params.

const KEYS = [
  "panel1","panel2","panel3"
] as const

function useAccordion<T extends Readonly<Array<string>>>(keys:T,defaultOpenKey: T[number]){
    // ...
}

useAccordion<typeof KEYS>(["panel1","panel2","panel3"], "panel1") // 2nd argument has to be one of the element from the keys(first argument)
useAccordion<typeof KEYS>(["panel1","panel2","panel3"], "panel7") // It should throw a typescript error 

CodePudding user response:

One method to achieve this would be to map the values in the array to a union type of the values in the array.

type ValueInArray<T extends unknown[]> = T extends [unknown, ...infer R] ? T[0] | ValueInArray<R> : never;

const a: ValueInArray<["a"]> = "a";
const b: ValueInArray<["a"]> = "b"; // error
const c: ValueInArray<["a", "b", "c"]> = "c";
const d: ValueInArray<["a", "b", "c"]> = "d"; // error

Check it out on the Playground.

  • Related