onT*_*net 24 javascript typescript
我有一些原始的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
Run Code Online (Sandbox Code Playgroud)
这按预期工作。我现在想将其转换为打字稿。
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
Run Code Online (Sandbox Code Playgroud)
但我收到以下错误。
元素隐式地具有“ any”类型,因为类型'string'的表达式不能用于索引类型'{“ A”:string; }'。在类型>'{“ A”:string;上找不到带有参数'string'的索引签名。}'。ts(7053)
我以为问题是我需要我的对象键是一个字符串。但是将它们转换为字符串不起作用。
DNATranscriber = {
"G":"C",
"C": "G",
"T": "A",
"A": "U"
}
Run Code Online (Sandbox Code Playgroud)
我对此很困惑。它说我的对象上不存在带有字符串类型的索引签名。但是我敢肯定。我究竟做错了什么?
编辑-我通过为DNATranscriber对象提供任何类型的对象来解决此问题。
DNATranscriber: any = {
"G":"C",
"C":"G",
"T":"A",
"A":"U"
}
Run Code Online (Sandbox Code Playgroud)
小智 46
在你的params你必须定义keyOf Object.
interface User {
name: string
age: number
}
const user: User = {
name: "someone",
age: 20
}
function getValue(key: keyof User) {
return user[key]
}
Run Code Online (Sandbox Code Playgroud)
小智 39
这是我为解决相关问题所做的工作
interface Map {
[key: string]: string | undefined
}
const HUMAN_MAP: Map = {
draft: "Draft",
}
export const human = (str: string) => HUMAN_MAP[str] || str
Run Code Online (Sandbox Code Playgroud)
Leo*_*uez 32
另外,您可以执行以下操作:
(this.DNATranscriber as any)[character];
Run Code Online (Sandbox Code Playgroud)
Ale*_*kay 17
不要使用任何,使用泛型
// bad
const _getKeyValue = (key: string) => (obj: object) => obj[key];
// better
const _getKeyValue_ = (key: string) => (obj: Record<string, any>) => obj[key];
// best
const getKeyValue = <T extends object, U extends keyof T>(key: U) => (obj: T) =>
obj[key];
Run Code Online (Sandbox Code Playgroud)
不好 - 错误的原因是object默认情况下类型只是一个空对象。因此不可能使用string类型来索引{}。
更好 - 错误消失的原因是因为现在我们告诉编译器obj参数将是字符串/值 ( string/any) 对的集合。但是,我们正在使用该any类型,因此我们可以做得更好。
最佳 -T扩展空对象。U扩展T. 因此U将始终存在于T,因此它可以用作查找值。
这是一个完整的例子:
我已经切换了泛型的顺序(U extends keyof T现在在之前T extends object)以强调泛型的顺序并不重要,您应该选择一个对您的函数最有意义的顺序。
const getKeyValue = <U extends keyof T, T extends object>(key: U) => (obj: T) =>
obj[key];
interface User {
name: string;
age: number;
}
const user: User = {
name: "John Smith",
age: 20
};
const getUserName = getKeyValue<keyof User, User>("name")(user);
// => 'John Smith'
Run Code Online (Sandbox Code Playgroud)
const getKeyValue = <T, K extends keyof T>(obj: T, key: K): T[K] => obj[key];
Run Code Online (Sandbox Code Playgroud)
Flá*_*les 14
您有两个简单且惯用的 Typescript 选项:
DNATranscriber: { [char: string]: string } = {
G: "C",
C: "G",
T: "A",
A: "U",
};
Run Code Online (Sandbox Code Playgroud)
这是错误消息所谈论的索引签名。参考
DNATranscriber: { G: string; C: string; T: string; A: string } = {
G: "C",
C: "G",
T: "A",
A: "U",
};
Run Code Online (Sandbox Code Playgroud)
Alu*_*dad 12
您可以通过验证输入来纠正错误,无论如何,这都是您应做的事情。
以下类型通过类型保护验证正确进行类型检查
const DNATranscriber = {
G: 'C',
C: 'G',
T: 'A',
A: 'U'
};
export default class Transcriptor {
toRna(sequence: string) {
const sequenceArray = [...sequence];
if (!isValidSequence(sequenceArray)) {
throw Error('invalid sequence');
}
const transcribedRNA = sequenceArray.map(codon => DNATranscriber[codon]);
return transcribedRNA;
}
}
function isValidSequence(codons: string[]): codons is Array<keyof typeof DNATranscriber> {
return codons.every(isValidCodon);
}
function isValidCodon(value: string): value is keyof typeof DNATranscriber {
return value in DNATranscriber;
}
Run Code Online (Sandbox Code Playgroud)
这是一个更惯用的版本
enum DNATranscriber {
G = 'C',
C = 'G',
T = 'A',
A = 'U'
}
export default function toRna(sequence: string) {
const sequenceArray = [...sequence];
if (!isValidSequence(sequenceArray)) {
throw Error('invalid sequence');
}
const transcribedRNA = sequenceArray.map(codon => DNATranscriber[codon]);
return transcribedRNA;
}
function isValidSequence(values: string[]): codons is Array<keyof typeof DNATranscriber> {
return values.every(isValidCodon);
}
function isValidCodon(value: string): value is keyof typeof DNATranscriber {
return value in DNATranscriber;
}
Run Code Online (Sandbox Code Playgroud)
请注意,我们如何利用TypeScript字符串枚举来提高清晰度并获得更强的碱基对映射类型。更重要的是,请注意我们如何使用function。这个很重要!将JavaScript转换为TypeScript与类无关,而与静态类型有关。
更新:
从TypeScript 3.7开始,我们可以更富有表现力地编写此代码,使用断言签名将输入验证及其类型含义之间的对应关系形式化。
enum DNATranscriber {
G = 'C',
C = 'G',
T = 'A',
A = 'U'
}
export default function toRna(sequence: string) {
const sequenceArray = [...sequence];
validateSequence(sequenceArray);
const transcribedRNA = sequenceArray.map(codon => DNATranscriber[codon]);
return transcribedRNA;
}
function validateSequence(values: string[]): asserts codons is Array<keyof typeof DNATranscriber> {
if (!values.every(isValidCodon)) {
throw Error('invalid sequence');
}
}
function isValidCodon(value: string): value is keyof typeof DNATranscriber {
return value in DNATranscriber;
}
Run Code Online (Sandbox Code Playgroud)
您可以在TypeScript 3.7发行说明中阅读有关断言签名的更多信息。
小智 11
例如,您可以使用记录。
let DNATranscriber: Record<string, string> = {};
Run Code Online (Sandbox Code Playgroud)
小智 10
这将消除错误并且是类型安全的:
this.DNATranscriber[character as keyof typeof DNATranscriber]
Run Code Online (Sandbox Code Playgroud)
我在我的getClass函数中解决了类似的问题,如下所示:
import { ApiGateway } from './api-gateway.class';
import { AppSync } from './app-sync.class';
import { Cognito } from './cognito.class';
export type stackInstances = typeof ApiGateway | typeof AppSync | typeof Cognito
export const classes = {
ApiGateway,
AppSync,
Cognito
} as {
[key: string]: stackInstances
};
export function getClass(name: string) {
return classes[name];
}
Run Code Online (Sandbox Code Playgroud)
classes用我的联合类型输入我的const 使打字稿很高兴,这对我来说很有意义。
小智 7
const Translator : { [key: string]: string } = {
G: "C",
C: "G",
T: "A",
A: "U"
}
export function toRna(DNA:string) {
const Translate = [...DNA];
let Values = Translate.map((dna) => Translator[dna])
if (Validate(Values)) {return Values.join('')}
}
export function Validate(Values:string[]) : Boolean{
if (Values.join('') === "" || Values.join('').length !== Values.length) throw Error('Invalid input DNA.');
return true
}
Run Code Online (Sandbox Code Playgroud)
小智 5
通过这样做解决了类似的问题:
export interface IItem extends Record<string, any> {
itemId: string;
price: number;
}
const item: IItem = { itemId: 'someId', price: 200 };
const fieldId = 'someid';
// gives you no errors and proper typing
item[fieldId]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18085 次 |
| 最近记录: |