### this is my mapping data structure saying: some contexts have specific own tags
const config = {
contexts: ["A", "B", "C"] as const,
tags: {
A: ["aa", "bb"] as const,
B: ["aa1", "bb1"] as const,
C: ["aa2", "bb2"] as const,
},
};
# union type for contexts possible
type C = typeof config.contexts[number]; // "A" | "B" | "C"
# union type for tags specific for context U
type F<U extends C> = typeof config.tags[U][number];
const a: C = config.contexts[1]; // OK "B"
const f: F<typeof a> = "aa1"; // OK will accept only 'aa1','bb1'
# then I tried the above into a couple of function def but with NO SUCCESS
const func = (a:C) => {
return (g:F<typeof a>) => {}
}
func('A')(g) // ERROR g can be all of : "aa" | "bb" | "aa1" | "bb1" | "aa2" | "bb2"
const func2 = (a:C,g:F<typeof a>) => {}
func('A',gg) // ERROR gg can be all of : "aa" | "bb" | "aa1" | "bb1" | "aa2" | "bb2"
CodePudding user response:
Using typoeof a
does not mean capturing the actual type of the argument passed in, it just means whatever the declared type of a
is, so in this case C
. It works in the first case, because TS will use control flow analysis to narrow the type of a
to B
, since that is local information, but it will not work for functions.
To capture call site information, you need to use a type parameter:
const func = <T extends C>(a:T) => {
return (g:F<T>) => {}
}
func('A')("bb") // ok
func('A')("bb1") // err