Query
Can types/interfaces be mapped to match the types of object instances, like a map
with objects as keys and types as values?
Demonstration
type StringKeys = {
foo: "foo" | "Foo",
bar: "bar" | "Bar"
}
function fooBar<T extends keyof StringKeys>(s: T, t: StringKeys[T]) {}
// Accurately maps types
fooBar('foo', 'Foo')
fooBar('bar', 'Bar')
// fooBar('bar', 'foo') ❌
/* --- OBJECTIVE --- */
class Buzz{
name: string
constructor(name: string) {
this.name = name;
}
greet() {
console.log(`Hi, I'm ${this.name}`)
}
getTitle():string {
return `Senior commander ${this.name}`
}
}
class Foo extends Buzz{
constructor(name: string) {
super(name);
}
getTitle():string {
return `Professor ${this.name} the Fourth`
}
}
class Bar extends Buzz{
constructor(name: string) {
super(name);
}
getTitle():string {
return `${this.name} the one and only.`
}
}
type GetValues<T extends Foo|Bar> = T extends Foo ? 'Foo' : T extends Bar ? 'Bar' : never
function fooBarObj<T extends Foo|Bar>(s: T, t: GetValues<T>){};
fooBarObj(new Foo('foo'), 'Foo')
fooBarObj(new Bar('bar'), 'Bar') // <- Error, expects 'Foo'
Usage Scenario
Similar to the example provided, my intention is to create a function that accepts a parameter which is an instance of one of several sibling classes, and enhances the type of the second parameter based on the specific class of the first parameter.