Reputation: 6338
I want to have a function with a arg of a certain type, and "matching" literal. How can I do that?
class T1 {
val: string = "abc"
}
class T2 {
val: number = 123
}
type TType = 'T1' | 'T2'
// I want to make this generic so the args have to "match"
function foo(ttype: TType, arg: T1 | T2) {
console.log(`${ttype}: arg.val`)
}
foo('T1', new T1)
foo('T2', new T2)
foo('T1', new T2) // I want this to be a compile-time error
I'd like the code to require that when 'T1' is passed as ttype
, an object of type T1 is required as the second arg and vice versa. I don't want two versions of the function if I can avoid that (don't want to copy the body) -- just a type spec that says "either literal T1 and a T1, or literal T2 and a T2". I'm happy to set up the mappings manually -- I don't need to get the class name from the string literal. Just don't know how to approach this in Typescript.
Upvotes: 0
Views: 95
Reputation: 250106
The simples approach is to use overloads
function foo(ttype: "T1", arg: T1): void
function foo(ttype: "T2", arg: T2): void
function foo(ttype: TType, arg: T1 | T2) {
console.log(`${ttype}: arg.val`)
}
You could also go with a generic function with a mapping interface, but for the example that would probably be overkill:
type TMap = {
"T1": T1
"T2": T2
}
// I want to make this generic so the args have to "match"
function foo<T extends TType>(ttype: T, arg: TMap[T]): void
function foo(ttype: TType, arg: T1 | T2) {
console.log(`${ttype}: arg.val`)
}
Upvotes: 4