Tengo un código javascript de vainilla que toma una entrada de cadena, divide la cadena en caracteres y luego hace coincidir esos caracteres con una clave en un objeto.
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 UGCACCAGAAUUEsto funciona como se esperaba. Ahora me gustaría convertir esto a mecanografiado.
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 TranscriptorPero estoy recibiendo el siguiente error.
El elemento implícitamente tiene un tipo 'cualquiera' porque la expresión de tipo 'cadena' > no se puede usar para indexar el tipo '{ "A": cadena; }'. No se encontró ninguna firma de índice con un parámetro de tipo 'cadena' en el tipo >'{ "A": cadena; }'.ts(7053)
Pensé que el problema era que necesitaba que mi clave de objeto fuera una cadena. Pero convertirlos en cadenas no funcionó.
DNATranscriber = { "G":"C", "C": "G", "T": "A", "A": "U" }Estoy bastante confundido por esto. Dice que no existe ninguna firma de índice con un tipo de cadena en mi objeto. Pero estoy seguro de que lo hace. ¿Qué estoy haciendo mal?
Editar: resolví esto dándole al objeto DNATranscriber un tipo cualquiera.
DNATranscriber: any = { "G":"C", "C":"G", "T":"A", "A":"U" }Además, puedes hacer esto:
(this.DNATranscriber as any)[character];Editar.
Se recomienda ENCARECIDAMENTE que emita el objeto con el tipo adecuado en lugar de any . Lanzar un objeto como any solo lo ayuda a evitar errores de tipo al compilar mecanografiado, pero no lo ayuda a mantener su código seguro.
P.ej
interface DNA { G: "C", C: "G", T: "A", A: "U" }Y luego lo lanzas así:
(this.DNATranscriber as DNA)[character];Puede corregir los errores validando su entrada, que es algo que debe hacer independientemente, por supuesto.
Las siguientes verificaciones de tipos correctamente, a través de validaciones de protección de tipos
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; }Vale la pena mencionar que parece tener la idea errónea de que convertir JavaScript a TypeScript implica el uso de clases.
En la siguiente versión, más idiomática, aprovechamos TypeScript para mejorar la claridad y obtener una tipificación más sólida de las asignaciones de pares de bases sin cambiar la implementación. Usamos una function , igual que la original, porque tiene sentido. ¡Esto es importante! Convertir JavaScript a TypeScript no tiene nada que ver con clases, tiene que ver con tipos estáticos.
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; }Actualizar :
Desde TypeScript 3.7, podemos escribir esto de manera más expresiva, formalizando la correspondencia entre la validación de entrada y su implicación de tipo usando firmas de aserción .
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; }Puede obtener más información sobre las firmas de afirmación en las notas de la versión de TypeScript 3.7 .
Esto fue lo que hice para resolver mi problema relacionado.
interface Map { [key: string]: string | undefined } const HUMAN_MAP: Map = { draft: "Draft", } export const human = (str: string) => HUMAN_MAP[str] || str