1

I have a function that accept string or string array and return an object with keys of those string.

Here is the dummy function:

type myType<T extends string> = { [K in T]: string }
const myFunc = <T extends string>(param: T | T[]): myType<T> => {
    let result = <myType<T>>{}
    // some codes here...
    return result;
}

With the above code, I already achieved this:

let val = myFunc(['foo', 'bar']);
val.foo // valid
val.other // invalid

But if I pass a variable to the function, all string keys are valid:

let variable = ['foo', 'bar'];
let val = myFunc(variable);
val.foo // valid
val.other // valid

Is there a workaround so I could pass a variable but still working as what I expected?

1
  • I think you need something along the lines of string extends T ? never : but I don't know what the syntax is for that Commented Mar 20, 2021 at 4:25

1 Answer 1

2

When you create a variable let variable = ['foo', 'bar'] the type of variable becomes string[] and you lose the knowledge of the specific strings in the array. You need to use as const in order for Typescript to interpret variable as fixed tuple of string literals 'foo' and 'bar'. Since this fixed tuple is readonly, you also need to modify your function to accept readonly arrays.

const myFunc = <T extends string>(param: T | readonly T[]): myType<T> => {
let variable = ['foo', 'bar'] as const;
let val2 = myFunc(variable);
val2.foo // valid
val2.other // invalid

Typescript Playground Link

Sign up to request clarification or add additional context in comments.

2 Comments

Is there a way to not using the as const? It's easy to forget adding it and there is no error thrown.
Well you can pass it directly to the function, but you've already said that you don't want to do that. You can assign an explicit type let variable: ['foo', 'bar'] = ['foo', 'bar'].

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.