#angular #typescript #typescript-generics
Вопрос:
У меня есть следующий пример.
enum Foo {
bar,
baz
}
interface IBar {
qux: number
}
interface IBaz {
quux: string
}
type InterfaceType<T> =
T extends Foo.bar ? IBar :
T extends Foo.baz ? IBaz : never;
interface ICorge<T> {
foo: T
attributes: InterfaceType<T>
}
const grault: Array<ICorge<unknown>> = [
{
foo: Foo.bar,
attributes: {
qux: 404
}
}, {
foo: Foo.baz,
attributes: {
quux: "not found"
}
}
]
Я хочу, чтобы тип моего интерфейса ICorge
автоматически определялся по типу foo
. Есть ли способ сделать это правильно в машинописном тексте?
Ответ №1:
Настоящая церемония с типами. Немного более практичное решение типа:
interface IBar {
foo: 'bar'
attributes: {
qux: number
}
}
interface IBaz {
foo: 'baz'
attributes: {
quux: string
}
}
const grault: (IBar | IBaz)[] = [
{
foo: 'bar',
attributes: {
qux: 44
}
}, {
foo: 'baz',
attributes: {
quux: "not found"
}
}
]
По крайней мере, я бы настоятельно не советовал enums
использовать производственный код без крайней необходимости.
Комментарии:
1. Это всего лишь простой пример из гораздо более сложной проблемы, и использование вашего решения добавило бы много повторений. Но из любопытства, почему бы вам не посоветовать против
enums
?2. Они создают много дополнительного кода и могут значительно снизить производительность при чрезмерном использовании. Я бы предположил
const enum
, что это хороший компромисс, если хотитеenums
.3. В любом случае.
InterfaceType
выглядит очень тяжелым. Вы можете достичь того же результата с помощью простого типа сопоставления: tsplay.dev/mbkRbW . или с перечислениями: tsplay.dev/mA7EXw
Ответ №2:
Правка: Извините, я |
сделал что-то не так.
Просто сделай:
const grault: Array<ICorge<Foo.bar> | ICorge<Foo.baz>> = [
{
foo: Foo.bar,
attributes: {
qux: 404
}
}, {
foo: Foo.baz,
attributes: {
quux: "not found"
}
}
]
Посмотрите на детскую площадку TS
Комментарии:
1. Это так просто, чем больше я открываю для себя универсальные шрифты, тем больше они мне нравятся. Спасибо.