Прежде всего, Record
- это просто объект. Аргумент первого типа - это тип ключей, а второй - тип значений. Это похоже на a Map
точно так же, как простой объект похож на Map
, оба они имеют значение для каждого набора ключей.
Если вам нужен реальный Map
, с api Map
, вам нужно фактически использовать и создать экземпляр Map
.
const DNAtoRNA: Map<DNA, RNA> = new Map()
DNAtoRNA.set('G', 'C')
DNAtoRNA.get('G') // 'C'
Но оставим это как объекты типа Record
.
Ошибка, которую вы получаете здесь:
return DNAtoRNA[el]
// Element implicitly has an 'any' type because expression of type
// 'string' can't be used to index type 'Record<DNA, RNA>'.
DNA
- это более конкретный тип c, чем строка. И Record<DNA, RNA>
гарантирует только то, что существует значение для ключей в DNA
, а не какая-либо строка.
Но el
здесь имеет тип string
, а не DNA
. Typescript предупреждает вас о том, что у вас может быть ошибка, и вы можете получить доступ к DNAtoRNA
с помощью недопустимого ключа.
Типичный способ исправить это с помощью typeguard, который выполняет проверку времени выполнения, чтобы подтвердить, что el
является безопасным значением для использования.
function isDNA(nucleotide: string): nucleotide is DNA {
return ['G', 'C', 'T', 'A'].includes(nucleotide)
}
Теперь вы можете проверить каждый нуклеотид, прежде чем использовать его для индексации вашей записи:
const translateDnaToRna = dna.split('').map(el => {
if (isDNA(el)) {
return DNAtoRNA[el]
} else {
throw new Error("bad data")
}
})
Playground (игнорировать ошибки типа для .includes
- это стандартная библиотека игровой площадки, в которой эта функция не определена)