打字稿:在类型'{“A”:字符串上找不到带有“字符串”类型参数的索引签名; }

新手上路,请多包涵

我有一些普通的 javascript 代码,它接受字符串输入,将字符串拆分为字符,然后将这些字符与对象上的键匹配。

DNATranscriber = {
    "G":"C",
    "C": "G",
    "T": "A",
    "A": "U"
}
function toRna(sequence){
    const sequenceArray = [...sequence];
    const transcriptionArray = sequenceArray.map(character =>{
        return this.DNATranscriber[character];
    });

    return transcriptionArray.join("");
}

console.log(toRna("ACGTGGTCTTAA")); //Returns UGCACCAGAAUU

这按预期工作。我现在想将其转换为打字稿。

class Transcriptor {
    DNATranscriber = {
       G:"C",
       C: "G",
       T: "A",
       A: "U"
    }
    toRna(sequence: string) {
        const sequenceArray = [...sequence];
        const transcriptionArray = sequenceArray.map(character =>{
            return this.DNATranscriber[character];
        });
    }
}

export default Transcriptor

但我收到以下错误。

元素隐式具有“任何”类型,因为“字符串”类型的表达式>不能用于索引类型“{“A”:字符串; }‘。

在 type >’{ “A”: string; 上找不到带有“string”类型参数的索引签名。 }‘.ts(7053)

我认为问题在于我需要我的对象键是一个字符串。但是将它们转换为字符串不起作用。

DNATranscriber = {
       "G":"C",
       "C": "G",
       "T": "A",
       "A": "U"
    }

我对此感到很困惑。它说我的对象上不存在具有字符串类型的索引签名。但我确信确实如此。我究竟做错了什么?

编辑 - 我通过给 DNATranscriber 对象一个类型来解决这个问题。

DNATranscriber: any = {
    "G":"C",
    "C":"G",
    "T":"A",
    "A":"U"
}

原文由 onTheInternet 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 481
2 个回答

您可以通过验证您的输入来修复错误,这是您无论如何都应该做的事情。

以下类型检查正确,通过类型保护验证

const DNATranscriber = {
 G: 'C',
 C: 'G',
 T: 'A',
 A: 'U'
 };

 export default class Transcriptor {
 toRna(dna: string) {
 const codons = [...dna];
 if (!isValidSequence(codons)) {
 throw Error('invalid sequence');
 }
 const transcribedRNA = codons.map(codon => DNATranscriber[codon]);
 return transcribedRNA;
 }
 }

 function isValidSequence(values: string[]): values is Array<keyof typeof DNATranscriber> {
 return values.every(isValidCodon);
 }
 function isValidCodon(value: string): value is keyof typeof DNATranscriber {
 return value in DNATranscriber;
 }

值得一提的是,您似乎误解了将 JavaScript 转换为 TypeScript 涉及使用类。

在以下更惯用的版本中,我们利用 TypeScript 来提高清晰度并在不更改实现的情况下获得更强的碱基对映射类型。我们使用一个 function ,就像原来的一样,因为它是有意义的。这个很重要!将 JavaScript 转换为 TypeScript 与类无关,它与静态类型有关。

 const DNATranscriber = {
 G: 'C',
 C: 'G',
 T: 'A',
 A: 'U'
 };

 export default function toRna(dna: string) {
 const codons = [...dna];
 if (!isValidSequence(codons)) {
 throw Error('invalid sequence');
 }
 const transcribedRNA = codons.map(codon => DNATranscriber[codon]);
 return transcribedRNA;
 }

 function isValidSequence(values: string[]): values is Array<keyof typeof DNATranscriber> {
 return values.every(isValidCodon);
 }
 function isValidCodon(value: string): value is keyof typeof DNATranscriber {
 return value in DNATranscriber;
 }

更新

从 TypeScript 3.7 开始,我们可以更富有表现力地编写它,使用 断言签名 将输入验证与其类型暗示之间的对应关系形式化。

 const DNATranscriber = {
 G: 'C',
 C: 'G',
 T: 'A',
 A: 'U'
 } as const;

 type DNACodon = keyof typeof DNATranscriber;
 type RNACodon = typeof DNATranscriber[DNACodon];

 export default function toRna(dna: string): RNACodon[] {
 const codons = [...dna];
 validateSequence(codons);
 const transcribedRNA = codons.map(codon => DNATranscriber[codon]);
 return transcribedRNA;
 }

 function validateSequence(values: string[]): asserts values is DNACodon[] {
 if (!values.every(isValidCodon)) {
 throw Error('invalid sequence');
 }
 }
 function isValidCodon(value: string): value is DNACodon {
 return value in DNATranscriber;
 }

您可以在 TypeScript 3.7 发行说明 中阅读有关 断言签名 的更多信息。

原文由 Aluan Haddad 发布,翻译遵循 CC BY-SA 4.0 许可协议

另外,您可以这样做:

 (this.DNATranscriber as any)[character];

编辑。

强烈 建议您使用正确的类型而不是 any 来转换对象。将对象转换为 any 只能帮助您在编译打字稿时避免类型错误,但不能帮助您保持代码类型安全。

例如

interface DNA {
    G: "C",
    C: "G",
    T: "A",
    A: "U"
}

然后你像这样投它:

 (this.DNATranscriber as DNA)[character];

原文由 Leonardo Emilio Dominguez 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题