Typescript 为什么我必须使用[el as type]来访问记录中的值?

Typescript 为什么我必须使用[el as type]来访问记录中的值?,typescript,Typescript,为什么我必须使用代码返回DNAtoRNA[el as DNA]来访问记录的值?当我尝试使用DNAtoRNA[el]访问它时,为什么会出现linting错误 而且,我相信TS中的记录与JS中的地图类似?如果是这样,为什么我不能使用get方法来检索值 谢谢 type DNA = 'G' | 'C' | 'T' | 'A'; type RNA = 'C' | 'G' | 'A' | 'U'; const DNAtoRNA: Record<DNA, RNA> = { 'G': 'C

为什么我必须使用代码
返回DNAtoRNA[el as DNA]
来访问记录的值?当我尝试使用
DNAtoRNA[el]
访问它时,为什么会出现linting错误

而且,我相信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('');
        }
    }
}
type DNA='G'|'C'|'T'|'A';
RNA类型='C'|'G'|'A'|'U';
常量DNA:记录={
‘G’:‘C’,
‘C’:‘G’,
‘T’:‘A’,
“A”:“U”
};
课堂记录员{
toRna(dna:字符串){
//常量formatInputOarr:string[]=dna.split(“”);
const translateDnaToRna=dna.split(“”).map(el=>{
返回DNAtoRNA[el作为DNA]
})
console.log(translateDnaToRna);
if(translateDnaToRna.includes(未定义)){
抛出新错误(“无效的输入DNA”);
}否则{
返回translateDnaToRna.join(“”);
}
}
}

首先,
记录
只是一个对象。第一个类型参数是键的类型,第二个是值的类型。它就像一个
贴图
,同样,一个普通对象就像一个
贴图
,它们都有一组键的值

如果您想要一个实际的
映射
,使用
映射
的api,您需要实际使用并实例化一个
映射

const DNAtoRNA: Map<DNA, RNA> = new Map()
DNAtoRNA.set('G', 'C')
DNAtoRNA.get('G') // 'C'
DNA
是比string更具体的类型。而
Record
只保证
DNA
中的键有一个值,而不是任何字符串

但是
el
这里的类型是
string
,而不是
DNA
。Typescript警告您可能存在错误,并且您可能正在使用无效密钥访问
DNAtoRNA

解决这个问题的typesafe方法是使用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")
    }
})

(忽略
的类型错误。includes
是否操场标准库没有定义该函数)

您好,感谢您的全面回复-非常有用。将
el视为dna
语句,这基本上就是说
在记录中找到一种dna类型的el索引
?这是最好的想法吗?不。
因为这是一个类型转换。这意味着程序员对这些变量的了解比typescript所能推断的要多
el-as-DNA
表示,即使
el
是一个
string
,程序员也可以断言
el
实际上是string
DNA
的子类型。无论你是否正确,打字脚本都会接受你的话。但是在这种情况下,如果您的
dna
包含不允许的字符,则转换将不正确,并且您可能有运行时错误。这就是为什么这里的类型保护函数很好,因为实际上您正在测试每个字符是否是正确的类型。
const translateDnaToRna = dna.split('').map(el => {
    if (isDNA(el)) {
        return DNAtoRNA[el]
    } else {
        throw new Error("bad data")
    }
})