타이프스크립트:유형 '{A": 문자열;}에서 매개 변수 유형이 'string'인 인덱스 서명을 찾을 수 없습니다.
문자열 입력을 받아 문자열을 문자로 분할한 후 오브젝트 상의 키에 일치시키는 바닐라 자바스크립트 코드를 가지고 있습니다.
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
하지만 다음과 같은 오류가 발생합니다.
유형 'string' > 의 식은 유형 '{A": string; }' 의 인덱스에 사용할 수 없기 때문에 요소에 암묵적인 유형이 있습니다.유형 >''문자열'' 매개 변수를 가진 인덱스 서명을 찾을 수 없습니다. {"A": 문자열; }.'ts(7053)
오브젝트 키가 문자열이어야 한다는 것이 문제라고 생각했습니다.하지만 그것들을 현으로 변환하는 것은 효과가 없었다.
DNATranscriber = {
"G":"C",
"C": "G",
"T": "A",
"A": "U"
}
나는 이것 때문에 꽤 혼란스럽다.오브젝트에 문자열의 종류가 있는 인덱스 시그니처가 존재하지 않는다고 표시됩니다.하지만 그럴 거라고 확신해요.내가 뭘 잘못하고 있지?
편집 - 이 문제를 해결하려면 DNATransscriber 개체에 any 유형을 지정합니다.
DNATranscriber: any = {
"G":"C",
"C":"G",
"T":"A",
"A":"U"
}
또, 다음과 같이 할 수 있습니다.
(this.DNATranscriber as any)[character];
편집.
오브젝트를 적절한 타입으로 캐스팅하는 것이 좋습니다.any
. 건을캐캐캐캐캐캐any
를 컴파일 할 때 할 수 뿐, 를 이 되지 않습니다.
예.
interface DNA {
G: "C",
C: "G",
T: "A",
A: "U"
}
그리고 이렇게 던집니다.
(this.DNATranscriber as DNA)[character];
입력 내용을 확인함으로써 오류를 수정할 수 있습니다.이것은, 어떠한 경우에도 실시할 필요가 있습니다.
다음 형식 보호 검증을 통해 올바른 형식 검사를 수행합니다.
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 릴리즈 노트를 참조하십시오.
이것이 나의 관련된 문제를 해결하기 위해 한 일이었다.
interface Map {
[key: string]: string | undefined
}
const HUMAN_MAP: Map = {
draft: "Draft",
}
export const human = (str: string) => HUMAN_MAP[str] || str
간단한 타입스크립트와 관용 타입스크립트의 2가지 옵션이 있습니다.
- 인덱스 유형 사용
DNATranscriber: { [char: string]: string } = {
G: "C",
C: "G",
T: "A",
A: "U",
};
오류 메시지가 나타내는 인덱스시그니처입니다레퍼런스
- 각 속성을 입력합니다.
DNATranscriber: { G: string; C: string; T: string; A: string } = {
G: "C",
C: "G",
T: "A",
A: "U",
};
아무 것도 사용하지 말고 제네릭을 사용
// 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];
Bad] : 은 [Bad] - [Bad]입니다.object
일 뿐입니다.type은 빈 개체입니다. 때문에 이렇게 할 수 string
에 {}
.
Better - 오류가 사라지게 된 이유는 컴파일러에 다음 명령을 전달하기 때문입니다.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'
대체 구문
const getKeyValue = <T, K extends keyof T>(obj: T, key: K): T[K] => obj[key];
이것으로 에러가 해소되어 타입이 세이프합니다.
this.DNATranscriber[character as keyof typeof DNATranscriber]
★★★★★★★★★★★★★★★★★★★★★★★에params
요.keyOf Object
.
interface User {
name: string
age: number
}
const user: User = {
name: "someone",
age: 20
}
function getValue(key: keyof User) {
return user[key]
}
같은 문제를 다음과 같이 해결:
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]
도 비슷한 했습니다.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];
}
의 내력을 입력하다classes
내 유니언 타입의 활자본을 행복하게 만들어줘서 그게 말이 돼.
예를 들어 Record를 사용할 수 있습니다.
let DNATranscriber: Record<string, string> = {};
Google 사용자:
형식에서 매개 변수가 'string'인 인덱스 서명을 찾을 수 없습니다...
대부분의 경우 오류는 다음과 같습니다.
요?
keyof Number
string
비슷한 타이핑 문제를 다음과 같은 코드로 해결했습니다.
const stringBasedKey = `SomeCustomString${someVar}` as keyof typeof YourTypeHere;
이 이슈는 오류의 진정한 의미를 이해하는 데 도움이 되었습니다.
이게 너한테 더 도움이 될 것 같아.
이 기능을 사용하면 인수를 입력할 때 제안사항을 얻을 수 있으며(편집기에서 시도), 나중에 사용할 수 있도록 강력한 반환 유형을 얻을 수 있습니다.
또한 Aluan Haddad의 답변에서 영감을 받아 시퀀스 검증이 이루어지지만 텍스트 루프 내에서 검증이 이루어지기 때문에 좀 더 효율적입니다.
type DNAletter = 'G' | 'C' | 'T' | 'A';
type RNAletter = 'C' | 'G' | 'A' | 'U';
const DNATranscriber: { [key in DNAletter]: RNAletter } = {
G: 'C',
C: 'G',
T: 'A',
A: 'U'
};
// Return `RNAletter[]`
function toRna(sequence: string | string[] | DNAletter[]) {
return ([...sequence] as DNAletter[]).map(character => {
const transcribed = DNATranscriber[character];
if (transcribed === undefined)
throw Error(`Invalid character "${character}" in sequence`);
return transcribed;
});
}
편집: TS3.4 이후로는 const로 사용할 수 있습니다.
한동안 이걸 가지고 놀았거든요.제 시나리오는 다음과 같습니다.
metrics1과 metrics2의 두 가지 유형이 있으며 각각 다른 속성을 가집니다.
type metrics1 = {
a: number;
b: number;
c: number;
}
type metrics2 = {
d: number;
e: number;
f: number;
}
이 오브젝트에는 모든 속성이 저장되어 있기 때문에 코드의 어느 시점에서 이 두 유형의 교차점에 있는 오브젝트를 만들었습니다.
const myMetrics: metrics1 & metrics2 = {
a: 10,
b: 20,
c: 30,
d: 40,
e: 50,
f: 60
};
이제 해당 개체의 속성을 동적으로 참조해야 합니다.여기서 인덱스 서명 오류가 발생합니다.컴파일 시간 체크와 런타임 체크를 기반으로 문제의 일부를 분석할 수 있습니다.const를 사용하여 객체를 참조하는 경우 TypeScript는 컴파일 중에 속성이 존재하는지 여부를 확인할 수 있기 때문에 이 오류는 표시되지 않습니다.
const myKey = 'a';
console.log(myMetrics[myKey]); // No issues, TypeScript has validated it exists
그러나 동적 변수(예를 들어 let)를 사용하는 경우 TypeScript는 컴파일 시간 동안 속성이 존재하는지 여부를 확인할 수 없으며 실행 시 추가 도움말이 필요합니다.여기서 다음 타입가드가 사용됩니다.
function isValidMetric(prop: string, obj: metrics1 & metrics2): prop is keyof (metrics1 & metrics2) {
return prop in obj;
}
이는 "obj에 속성 프로포스트가 있는 경우 TypeScript에 메트릭스1과 메트릭스2의 교차점에 프로포트가 존재함을 알립니다."라고 쓰여 있습니다.주의: 위의 키 뒤에 반드시 metrics1과 metrics2를 괄호로 둘러싸십시오.그렇지 않으면 metrics1의 키와 metrics2의 유형(키가 아님)이 교차합니다.
이제 typeguard를 사용하여 런타임 중에 개체에 안전하게 액세스할 수 있습니다.
let myKey:string = '';
myKey = 'a';
if (isValidMetric(myKey, myMetrics)) {
console.log(myMetrics[myKey]);
}
저의 해결책은
type DNATranscriber = {
G: string,
C: string,
T: string,
A: string,
}
type DNATanscriberIndex = {
[key: string]: string
}
let variableName:DNATanscriberIndex&DNATanscriber
DNATransscriber 타입은 Typescript가 필드 및 DNATanscriber를 참조할 수 있도록 하기 위한 것입니다.인덱스 유형은 인덱스를 문자열로 선언하는 것입니다.
다음은 어레이 개체의 일반적인 유형 트리밍 함수 예제입니다.
const trimArrayObject = <T>(items: T[]) => {
items.forEach(function (o) {
for (let [key, value] of Object.entries(o)) {
const keyName = <keyof typeof o>key;
if (Array.isArray(value)) {
trimArrayObject(value);
} else if (typeof o[keyName] === "string") {
o[keyName] = value.trim();
}
}
});
};
오브젝트 키를 사용하지 않고 이 문제를 해결할 수 있는 방법은 다음과 같습니다.
function toRna(value: string): string {
return value.split('').map(ch => 'CGAU'['GCTA'.indexOf(ch)]).join('');
}
console.log(toRna('ACGTGGTCTTAA'));
\\UGCACCAGAAUU
이렇게 반환 유형을 사용하여 얻을 수 있습니다.
getAllProperties(SellRent: number) : Observable<IProperty[]>{
return this.http.get<IProperty[]>('data/properties.json').pipe(
map(data => {
const propertiesArray: Array<IProperty> = [];
for(const id in data){
if(data.hasOwnProperty(id) && data[id].SellRent === SellRent){
propertiesArray.push(data[id]);
}
}
return propertiesArray;
})
)
}
오래된 질문인 것은 알지만, TS는 질문을 받았을 때보다 문제를 쉽게 입력할 수 있는 방법을 제공합니다.TS3.4에서 가장 심플한 접근방식은 "항상"을 사용하는 것입니다.객체를 입력하는 것은 결코 올바른 솔루션 IMO가 아닙니다.
DNATranscriber = {
"G":"C",
"C": "G",
"T": "A",
"A": "U"
} as const;
이는 이제 ts가 이러한 키와 값이 변경되지 않는다는 것을 알았으므로 유추로 평가할 수 있음을 의미합니다.즉, TS는 이미 그 DNATransscriber를 인식하고 있습니다.G]가 "C"가 되어 출력 코드를 체크할 수 있습니다.이것은, 한층 더 도움이 됩니다.
지난 이야기...Marias의 답변과 같다.
type Keys = "G" | "C" | "T" | "A";
type values "C" | "G" | "A" | "U";
DNATranscriber: {[K in Keys]: values} = {
"G":"C",
"C": "G",
"T": "A",
"A": "U"
};
매핑의 정적 특성을 나타내지 않았기 때문에 이상적이지 않습니다.
간단한 해결 방법은 다음과 같습니다.
(obj as { [k in string]: any })[key]
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
}
유사한 사례로 어려움을 겪고 있는 모든 분들을 위해
No index signature with a parameter of type 'string' was found on type X
다음과 같은 단순한 오브젝트(dict로 사용)와 함께 사용하려고 합니다.
DNATranscriber = {
G:"C",
C: "G",
T: "A",
A: "U"
}
다음과 같이 계산된 키에서 값에 동적으로 액세스하려고 합니다.
const key = getFirstType(dnaChain);
const result = DNATranscriber[key];
그리고 당신은 위와 같은 에러를 직면했고, 당신은 연산자 키를 사용하여 다음과 같은 것을 시도할 수 있습니다.
const key = getFirstType(dnaChain) as keyof typeof DNATranscriber;
result
다만, 커스텀 타입의 마법보다 직관적으로 느껴진다면 괜찮습니다.
언급URL : https://stackoverflow.com/questions/56568423/typescript-no-index-signature-with-a-parameter-of-type-string-was-found-on-ty
'programing' 카테고리의 다른 글
Base64 데이터 URI에서 PNG 이미지 서버 측을 저장하는 방법 (0) | 2022.09.25 |
---|---|
MariaDB/MySQL: "UTC" 시간대가 "+00:00" 시간대와 같습니까? (0) | 2022.09.25 |
i18n의 현재 로케일의 변경을 감시할 수 있는 방법이 있습니까? (0) | 2022.09.25 |
mockito 콜백 및 인수값 가져오기 (0) | 2022.09.25 |
HTML/PHP에 의한 XSS 방지 방법 (0) | 2022.09.25 |