0

So I have a string union type

type S = 'a' | 'b' | 'c';

I want to initialize a value of type S, while asserting that is of type S. With a variable, it's very easy:

const s1: S = 'a';
const s2: S = 'z'; // error

However, I just want to instantiate the value itself, along the lines of 'a' as S but checking that 'a' is of type S.

The exact use case is that I'm using a library that provides a function f(s: string), but I want to ensure that when I call it, I only call it with the strings I deem ok. Since [afaik] you can't narrow the signature from outside the library, I was thinking of doing something like f('a' as S) every time I used f.

Defining my own function g = (s: S) => f(s) isn't a great option because actually f's signature looks like f(s: string, t: T) where T is a complex, library defined type that I'm not sure is even exported.

What would be the best way to accomplish this?

2 Answers 2

2

Wrap the external function with your own using the string type (TS playground):

const externalFn = <T>(s: string, t: T) => t

type S = 'a' | 'b' | 'c';

const yourFn = (s: S, t: Parameters<typeof externalFn>[1]) => externalFn(s, t)

If you need to handle a function with more than one argument, you can use the idea in this answer (TS playground):

type DropFirst<T extends unknown[]> = T extends [any, ...infer U] ? U : never

const externalFn = <T>(s: string, t: T) => t

type S = 'a' | 'b' | 'c';

const yourFn = (s: S, ...rest: DropFirst<Parameters<typeof externalFn>>) => externalFn(s, ...rest)
Sign up to request clarification or add additional context in comments.

5 Comments

Ah sorry I just edited my post so I wouldn't get this answer :/
See updated answer
thanks! In the case where f has multiple such parameters, is there an extensible solution?
links seem to be broken now
0

I ended up making a simple wrapper function like so:

function ok<T extends string>(s: T): T {
  return s;
}

that I could then use like f(ok<S>('a')), because in my case there were multiple functions and types that I wanted to do this verification for, and making a separate wrapping function would be tedious and not maintainable.

2 Comments

side note: Initially, intellij was giving me autocomplete suggestions for these strings (they were actually template literal types)--then I did something (I wish I knew what) and now it stopped :( Does anyone know how to ensure intellij is autocompleting them?
it was because there were too many possibilities for my template literals

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.