Почему я должен использовать [el as type] для доступа к значению в записи? - PullRequest
0 голосов
/ 04 августа 2020

Почему я должен использовать код return DNAtoRNA[el as DNA] для доступа к значению записи? и почему я получаю ошибку линтинга, когда пытаюсь получить к нему доступ, используя DNAtoRNA[el]?

Кроме того, мне дали поверить, что запись в TS похожа на карту в JS? Если да, то почему я не могу использовать метод get для получения значения?

Спасибо!

type DNA = 'G' | 'C' | 'T' | 'A';
type RNA = 'C' | 'G' | 'A' | 'U';

const DNAtoRNA: Record<DNA, RNA> = {
    'G': 'C',
    'C': 'G',
    'T': 'A',
    'A': 'U'
};

class Transcriptor {
    toRna(dna: string) {
        //const formatInputToArr: string[] = dna.split('');
        const translateDnaToRna = dna.split('').map(el => {
            return DNAtoRNA[el as DNA]
        })

        console.log(translateDnaToRna);

        if (translateDnaToRna.includes(undefined)) {
            throw new Error('Invalid input DNA.');
        } else {
            return translateDnaToRna.join('');
        }
    }
}

1 Ответ

1 голос
/ 04 августа 2020

Прежде всего, 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 - это стандартная библиотека игровой площадки, в которой эта функция не определена)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...