Type Script:형식에 인덱스 서명이 없습니다.
는 는고되 i i i want want i를 원한다.MyInterface.dic
과 name: value
뭇매를 맞다
interface MyInterface {
dic: { [name: string]: number }
}
이제 내 유형을 기다리는 함수를 만듭니다.
function foo(a: MyInterface) {
...
}
그리고 입력:
let o = {
dic: {
'a': 3,
'b': 5
}
}
하고 있다foo(o)
컴파일러가 다운되고 있습니다.
foo(o) // TypeScript error: Index signature is missing in type { 'a': number, 'b': number }
수 있다는 것을 있습니다.let o: MyInterface = { ... }
TypeScript가 내 타입을 인식하지 못하는 이유는 무엇입니까?
추가: 다음과 같은 경우 정상적으로 동작합니다.o
: is is is is is is is is is 。
foo({
dic: {
'a': 3,
'b': 5
}
})
때 ''이 '유형'이라는입니다.o
말합니다
{ dic: { a: number, b: number } }
건지같 와 같지 .{ dic: { [name: string]: number } }
중요한 것은 맨 o.dic['x'] = 1
두 번째 서명으로.
실행 시 동일한 유형(실제로 동일한 값)이지만, TypeScript의 안전성의 큰 부분은 이러한 유형이 동일하지 않다는 사실과 개체를 사전으로 취급하도록 명시적으로 의도된 경우에만 허용한다는 사실에서 비롯됩니다.이로 인해 객체에 전혀 존재하지 않는 속성을 실수로 읽고 쓸 수 없게 됩니다.
해결책은 TypeScript가 사전으로서 의도된 것임을 확실히 하는 것입니다.즉, 다음과 같습니다.
사전임을 나타내는 유형을 명시적으로 제공:
let o: MyInterface
사전 인라인이라고 단언하는 방법:
let o = { dic: <{ [name: string]: number }> { 'a': 1, 'b': 2 } }
TypeScript가 제공하는 초기 유형을 확인합니다.
foo({ dic: { 'a': 1, 'b': 2 } })
만약 TypeScript가 2개의 속성만을 가진 일반 오브젝트라고 생각하고 나중에 사전으로 사용하려고 한다면, 그것은 좋지 않을 것입니다.
TS는 우리가 지수의 종류를 정의하기를 원합니다.예를 들어, 컴파일러에 임의의 문자열로 오브젝트를 인덱싱할 수 있음을 알립니다.myObj['anyString']
, 경::
interface MyInterface {
myVal: string;
}
대상:
interface MyInterface {
[key: string]: string;
myVal: string;
}
이제 임의의 문자열 인덱스에 임의의 문자열 값을 저장할 수 있습니다.
x['myVal'] = 'hello world'
x['any other string'] = 'any other string'
저는 인터페이스 대신 타입을 사용하여 오류를 해결했습니다.
는 함수 '이러면 안 돼요'가할 수 .foo
에는 다음과 같은 입력 파라미터의 인터페이스 대신 타입이 있습니다.
type MyType {
dic: { [name: string]: number }
}
function foo(a: MyType) {}
그러나 전달된 값은 다음과 같은 인터페이스로 입력됩니다.
interface MyInterface {
dic: { [name: string]: number }
}
const o: MyInterface = {
dic: {
'a': 3,
'b': 5
}
}
foo(o) // type error here
그냥 사용했어요
const o: MyType = {
dic: {
'a': 3,
'b': 5
}
}
foo(o) // It works
제, 냥, 냥, 냥, 냥을 거였어요.type
interface
.
제 의견은 이렇습니다.
type Copy<T> = { [K in keyof T]: T[K] }
genericFunc<SomeType>() // No index signature
genericFunc<Copy<SomeType>>() // No error
이 오류는 정당한 것입니다.대신 다음 코드를 작성하여 유형을 불변으로 표시해야 합니다.
interface MyInterface {
dic: { [name: string]: number }
}
function foo(a: MyInterface) {
...
}
const o = Object.freeze({
dic: {
'a': 3,
'b': 5
}
})
왜요?
는 TypeScript가 음음음음음음음음음 that that the the the the that that that that 라고 가정할 수 .o
과 시간 에 foo(o)
출됩니니다다
코드 어딘가에 다음과 같은 내용이 적혀 있을 수 있습니다.
delete o.dic.a;
이것이 인라인 버전이 작동하는 이유입니다.이 경우 업데이트는 불가능합니다.
다음의 간단한 트릭도 도움이 될 수 있습니다.
type ConvertInterfaceToDict<T> = {
[K in keyof T]: T[K];
};
이 변환은 문제를 해결하는 데 도움이 되었습니다.
'QueryParameters' 형식의 인수는 'Record<string, string> 유형의 매개 변수에 할당할 수 없습니다.
여기서 QueryParameters는 인터페이스입니다.서드파티 패키지로 직접 수정하지 못했습니다.
이 문제는 OP의 질문보다 조금 더 광범위합니다.
예를 들어 인터페이스의 인터페이스와 변수를 정의합니다.
interface IObj {
prop: string;
}
const obj: IObj = { prop: 'string' };
''를 할당할 수 요?obj
Record<string, string>
대답은 '아니오'입니다.데모
// TS2322: Type 'IObj' is not assignable to type 'Record<string, string>'. Index signature for type 'string' is missing in type 'IObj'.
const record: Record<string, string> = obj;
왜 이런 일이 일어나는 거죠?이를 설명하기 위해 "업캐스팅"과 "다운캐스팅" 용어에 대한 이해와 SOLID 원칙에서 "L"자의 의미가 무엇인지 다시 한 번 살펴보겠습니다.
다음 예시는 "wider" 유형을 보다 엄격한 유형에 할당하기 때문에 오류 없이 작동합니다.
const initialObj = {
title: 'title',
value: 42,
};
interface IObj {
title: string;
}
const obj: IObj = initialObj; // No error here
obj.title;
obj.value; // Property 'value' does not exist on type 'IObj'.(2339)
IObj
하나의 소품만 필요하기 때문에 할당은 정확합니다.
타입도 마찬가지입니다.데모
const initialObj = {
title: 'title',
value: 42,
};
type TObj = {
title: string;
}
const obj: TObj = initialObj; // No error here
obj.title;
obj.value; // Property 'value' does not exist on type 'TObj'.(2339)
마지막 두 예는 "업캐스트" 때문에 오류 없이 작동합니다.즉, 값 유형을 "위" 유형, 즉 상위 유형일 수 있는 엔티티 유형으로 캐스팅합니다.즉, 개를 동물에게 할당할 수는 있지만 동물을 개에게 할당할 수는 없습니다(솔리드 원칙에서 "L"자의 의미 참조).개를 동물에게 할당하는 것은 "업캐스트"이며 이는 안전한 작업입니다.
Record<string, string>
하나의 속성을 가진 물체보다 훨씬 넓습니다.을 사용하다
const fn = (record: Record<string, string>) => {
record.value1;
record.value2;
record.value3; // No errors here
}
때문에 '아예'를 붙일 때 '아예'를 붙일 때IObj
""에 대한 Record<string, string>
에러가 표시됩니다.확장되는 유형에 할당합니다.IObj
Record<string, string>
은 형은 の antant の antantantantant의 수.IObj
.
다른 답변에서는 Type을 사용하면 문제를 해결할 수 있다고 언급되어 있습니다.하지만 나는 그것이 잘못된 행동이고 우리는 그것을 사용하는 것을 피해야 한다고 생각한다.
type TObj = {
title: string;
}
const obj: TObj = {
title: 'title',
};
const fn = (record: Record<string, string>) => {
record.value1;
record.value2;
// No errors here because according to types any string property is correct
record.value3;
}
fn(obj); // No error here but it has to be here because of downcasting
추신.
이 문제를 관련 질문과 흥미로운 코멘트로 살펴보십시오.
이것이 검색어 상위 결과인 것 같습니다.(string, string)이 있는 인덱스 유형이 이미 있고 해당 입력 유형을 변경할 수 없는 경우 다음을 수행할 수도 있습니다.
foo({...o}) // Magic
또 다른 방법은 다음과 같습니다.
interface MyInterface {
[name: string]: number
}
function foo(a: MyInterface) {
...
}
let o = {
'a': 3,
'b': 5
}
foo(o);
언급URL : https://stackoverflow.com/questions/37006008/typescript-index-signature-is-missing-in-type
'programing' 카테고리의 다른 글
오류: 파일을 찾을 수 없습니다. 'index.js'가 디스크의 해당 이름과 일치하지 않습니다. '.node_modules/React/React' (0) | 2023.04.05 |
---|---|
Larabel 4에서 웅변 모델을 JSON으로 반환 (0) | 2023.03.31 |
Google reCaptcha 재설정이 작동하지 않습니다. (0) | 2023.03.31 |
2개의 인터페이스의 Marge (0) | 2023.03.31 |
죄송합니다. 선택하신 제품과 일치하는 제품이 없습니다.다른 조합의 WooCommerce를 선택하십시오. (0) | 2023.03.31 |