Свойство интерфейса из класса typescript
Как указать ts брать имя свойства интерфейса из экземпляра класса, который нужно найти по ключу из значения другого свойства?
class A {aaa: number = 1;}
class B {bbb: number = 2;}
class C {ccc: number = 3;}
interface I {
qwerty: A;
abcde: B;
zzz: C;
}
interface Test<T extends keyof I, K = I[T]> {
test1: T;
[M: keyof K]: K[typeof M]; // typeof K[M] ???
}
function load<T extends keyof I>(test: Test<T>): void {}
load({
test1: 'abcde',
bbb: 50, // Argument of type '{ test1: "abcde"; bbb: number; }' is not assignable to parameter of type 'Test<"abcde", B>'. Object literal may only specify known properties, and 'bbb' does not exist in type 'Test<"abcde", B>'
});
Ответы (2 шт):
Автор решения: Gayrat Vlasov
→ Ссылка
Воспользуйтесь type guards, например:
class A {
aaa = 1;
kind: 'typeA' = 'typeA';
}
class B {
bbb = 2;
kind: 'typeB' = 'typeB';
}
function load(test: A | B) {
if (test.kind === 'typeA') {
console.log(test.aaa);
} else {
console.log(test.bbb);
}
}
load({
aaa: 2,
kind: 'typeA',
});
Автор решения: Grundy
→ Ссылка
Вместо интерфейса нужно использовать mapped types
type Test<T extends keyof I, K = I[T]> = {
test1: T;
} & {
[M in keyof K]: K[M];
}
В этом случае к обязательному полю test1 добавляются все поля соответствующего класса