noImplicitAny 플래그가 활성화된 형식 스크립트를 컴파일할 때 "Index signature of object type is implicitly has a 'any' type" 오류를 방지하려면 어떻게 해야 합니까?
항상 플래그를 사용하여 TypeScript를 컴파일합니다.--noImplicitAny
제 타입의 체크는 가능한 한 엄격하게 하고 싶기 때문에, 이것은 타당합니다.
문제는 다음 코드를 사용하면 오류가 발생한다는 것입니다.
Index signature of object type implicitly has an 'any' type
interface ISomeObject {
firstKey: string;
secondKey: string;
thirdKey: string;
}
let someObject: ISomeObject = {
firstKey: 'firstValue',
secondKey: 'secondValue',
thirdKey: 'thirdValue'
};
let key: string = 'secondKey';
let secondValue: string = someObject[key];
주의할 점은 키 변수가 어플리케이션의 다른 곳에서 온 것으로 오브젝트 내의 임의의 키가 될 수 있다는 것입니다.
저는 다음과 같은 방법으로 그 활자를 캐스팅하려고 했습니다.
let secondValue: string = <string>someObject[key];
아니면 내 시나리오가 그냥 안 되는 건가?--noImplicitAny
?
인덱스 시그니처를 추가하면 TypeScript는 어떤 타입이어야 하는지 알 수 있습니다.
당신의 경우, 그것은[key: string]: string;
interface ISomeObject {
firstKey: string;
secondKey: string;
thirdKey: string;
[key: string]: string;
}
그러나 이렇게 하면 모든 속성 유형이 인덱스 서명과 일치합니다.모든 속성이 다string
그건 효과가 있다.
인덱스 서명은 배열 및 '사전' 패턴을 설명하는 강력한 방법이지만 모든 속성이 반환 유형과 일치하도록 강제하기도 합니다.
편집:
유형이 일치하지 않으면 유니언 유형을 사용할 수 있습니다.[key: string]: string|IOtherObject;
유니언 타입에서는 TypeScript가 타입을 정의하지 않고 유추하도록 하는 것이 좋습니다.
// Type of `secondValue` is `string|IOtherObject`
let secondValue = someObject[key];
// Type of `foo` is `string`
let foo = secondValue + '';
인덱스 시그니처에 다른 타입이 많이 있는 경우는, 조금 혼란스러울 수 있습니다.그에 대한 대안은 다음과 같습니다.any
서명에 기재되어 있습니다. [key: string]: any;
그리고 위에서 했던 것처럼 활자를 캐스팅해야 합니다.
오류를 방지하는 또 다른 방법은 다음과 같이 깁스를 사용하는 것입니다.
let secondValue: string = (<any>someObject)[key];
(괄호 주의)
유일한 문제는 이것이 더 이상 타입 세이프가 아니라는 것입니다.any
하지만 항상 올바른 타입으로 되돌릴 수 있습니다.
ps: 타입스크립트 1.7을 사용하고 있는데 이전 버전은 잘 모르겠습니다.
TypeScript 2.1에서는 이 문제를 해결하는 우아한 방법이 도입되었습니다.
const key: (keyof ISomeObject) = 'secondKey';
const secondValue: string = someObject[key];
컴파일 단계 중 다음 방법으로 모든 개체 속성 이름에 액세스할 수 있습니다.keyof
키워드(changelog 참조).
교환만 하면 됩니다.string
변수형keyof ISomeObject
컴파일러는 알고 있습니다.key
변수는 다음 속성 이름만 포함할 수 있습니다.ISomeObject
.
완전한 예:
interface ISomeObject {
firstKey: string;
secondKey: string;
thirdKey: number;
}
const someObject: ISomeObject = {
firstKey: 'firstValue',
secondKey: 'secondValue',
thirdKey: 3
};
const key: (keyof ISomeObject) = 'secondKey';
const secondValue: string = someObject[key];
// You can mix types in interface, keyof will know which types you refer to.
const keyNumber: (keyof ISomeObject) = 'thirdKey';
const numberValue: number = someObject[keyNumber];
라이브 코드는 typescriptlang.org (세트)noImplicitAny
옵션)
다음 tsconfig 설정을 사용하면 이러한 오류를 무시할 수 있습니다. true로 설정합니다.
suppress Implicit Any(임의)인덱스 에러
noImplicit 억제인덱스 서명이 없는 인덱스 개체에 대한 오류입니다.
keyof typeof
const cat = {
name: 'tuntun'
}
const key: string = 'name'
cat[key as keyof typeof cat]
위의 '키오프' 솔루션이 작동합니다.단, 오브젝트를 루프하는 등 변수가 한 번만 사용되는 경우에는 이를 타이프캐스트할 수도 있습니다.
for (const key in someObject) {
sampleObject[key] = someObject[key as keyof ISomeObject];
}
이렇게 선언해 주세요.
export interface Thread {
id:number;
messageIds: number[];
participants: {
[key:number]: number
};
}
인터페이스를 생성하여 '인덱서' 인터페이스를 정의합니다.
그런 다음 해당 인덱스로 개체를 만듭니다.
주의: 다른 답변에서도 각 항목의 유형 적용과 관련하여 설명한 것과 동일한 문제가 발생하지만, 대부분의 경우 이 문제가 바로 당신이 원하는 것입니다.
수 .ObjectIndexer< Dog | Cat>
// this should be global somewhere, or you may already be
// using a library that provides such a type
export interface ObjectIndexer<T> {
[id: string]: T;
}
interface ISomeObject extends ObjectIndexer<string>
{
firstKey: string;
secondKey: string;
thirdKey: string;
}
let someObject: ISomeObject = {
firstKey: 'firstValue',
secondKey: 'secondValue',
thirdKey: 'thirdValue'
};
let key: string = 'secondKey';
let secondValue: string = someObject[key];
범용 타입을 정의할 때 범용 제약조건으로 사용할 수도 있습니다.
export class SmartFormGroup<T extends IndexableObject<any>> extends FormGroup
★★★★★★★★★★★★★★★.T
을 할 수 . :-)를 색인화할 수 있습니다.
인덱서가 없습니까?그럼 직접 만들어봐!
오브젝트 시그니처를 쉽게 정의할 수 있도록 글로벌하게 정의했습니다. T
수 있습니다.any
다음 중 하나:
type Indexer<T> = { [ key: string ]: T };
덧붙일 뿐입니다.indexer
급의의일일일일일
indexer = this as unknown as Indexer<Fruit>;
그래서 이렇게 끝납니다.
constructor(private breakpointResponsiveService: FeatureBoxBreakpointResponsiveService) {
}
apple: Fruit<string>;
pear: Fruit<string>;
// just a reference to 'this' at runtime
indexer = this as unknown as Indexer<Fruit>;
something() {
this.indexer['apple'] = ... // typed as Fruit
점이 , 이렇게 수 .많은 솔루션에서는<any>
타이핑이 손실됩니다.런타임 검증은 수행되지 않습니다.만약 당신이 그것이 존재하는지 확실히 모른다면 당신은 여전히 그것이 존재하는지 확인해야 할 것이다.
때, 조심하고 때, 조심하고 싶을 때, 너무 조심하고 싶을 때, 너무 조심하고 싶을 때, 너무 조심하고 싶어요.strict
이를 통해 명시적으로 정의되지 않은 검사를 수행해야 할 모든 위치를 표시할 수 있습니다.
type OptionalIndexed<T> = { [ key: string ]: T | undefined };
다른 곳에서 문자열 속성으로 사용할 경우 일반적으로 유효하다는 것을 알 수 있기 때문에 이 기능이 필요하지 않습니다.
이 방법은 인덱서에 액세스해야 하는 코드가 많고 한 곳에서만 입력을 변경할 수 있는 경우에 특히 유용합니다.
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★」strict
및 "displaces" 입니다.unknown
꼭 필요합니다.
는 「」입니다.indexer = this
을 만들 때랑 비슷해요._this = this
널 위해서.
@ @Piotr Lewandowski의 답변 forEach
:
const config: MyConfig = { ... };
Object.keys(config)
.forEach((key: keyof MyConfig) => {
if (config[key]) {
// ...
}
});
키가 문자열이고 값이 임의인 유형을 선언한 후 이 유형을 사용하여 개체를 선언하면 보풀이 나타나지 않습니다.
type MyType = {[key: string]: any};
그래서 당신의 코드는
type ISomeType = {[key: string]: any};
let someObject: ISomeType = {
firstKey: 'firstValue',
secondKey: 'secondValue',
thirdKey: 'thirdValue'
};
let key: string = 'secondKey';
let secondValue: string = someObject[key];
Typescript 3.1을 사용하여 3단계에서 찾을 수 있는 가장 간단한 솔루션은 다음과 같습니다.
1) 인터페이스 만들기
interface IOriginal {
original: { [key: string]: any }
}
2) 타이프 복사하기
let copy: IOriginal = (original as any)[key];
3) 어디서나 사용 (JSX 포함)
<input customProp={copy} />
오늘날에는 유형을 선언하는 것이 더 나은 해결책입니다.맘에 들다
enum SomeObjectKeys {
firstKey = 'firstKey',
secondKey = 'secondKey',
thirdKey = 'thirdKey',
}
let someObject: Record<SomeObjectKeys, string> = {
firstKey: 'firstValue',
secondKey: 'secondValue',
thirdKey: 'thirdValue',
};
let key: SomeObjectKeys = 'secondKey';
let secondValue: string = someObject[key];
인터페이스가 2개 있었어요.첫째는 다른 사람의 아이였다.다음을 수행했습니다.
- 부모 인터페이스에 인덱스 시그니처가 추가되었습니다.
- 를 사용하다
as
키워드를 지정합니다.
전체 코드는 다음과 같습니다.
자 인터페이스:
interface UVAmount {
amount: number;
price: number;
quantity: number;
};
부모 인터페이스:
interface UVItem {
// This is index signature which compiler is complaining about.
// Here we are mentioning key will string and value will any of the types mentioned.
[key: string]: UVAmount | string | number | object;
name: string;
initial: UVAmount;
rating: number;
others: object;
};
반응 컴포넌트:
let valueType = 'initial';
function getTotal(item: UVItem) {
// as keyword is the dealbreaker.
// If you don't use it, it will take string type by default and show errors.
let itemValue = item[valueType] as UVAmount;
return itemValue.price * itemValue.quantity;
}
를를 there there there an an an an an an an를 쓸 .ObjectIndexer<T>
또는 원래 개체의 인터페이스를 변경합니다(다른 대부분의 답변에서 권장되는 것과 같음).다음과 같이 키 옵션을 문자열 유형으로 좁힐 수 있습니다.
type KeysMatching<T, V> = { [K in keyof T]: T[K] extends V ? K : never }[keyof T];
이 훌륭한 해결책은 여기에 있는 관련 질문에 대한 답변에서 나온 것입니다.
이렇게 해서 V 값을 가지고 있는 T 내의 키로 좁힙니다.따라서 문자열로 제한하려면 다음 작업을 수행합니다.
type KeysMatching<ISomeObject, string>;
이 예에서는 다음과 같습니다.
interface ISomeObject {
firstKey: string;
secondKey: string;
thirdKey: string;
}
let someObject: ISomeObject = {
firstKey: 'firstValue',
secondKey: 'secondValue',
thirdKey: 'thirdValue'
};
let key: KeysMatching<SomeObject, string> = 'secondKey';
// secondValue narrowed to string
let secondValue = someObject[key];
의 점으,,,ISomeObject
는 혼합형도 유지할 수 있게 되었습니다.또한 키를 문자열 값만으로 좁힐 수 있습니다.하다★★★★
interface ISomeObject {
firstKey: string;
secondKey: string;
thirdKey: string;
fourthKey: boolean;
}
let someObject: ISomeObject = {
firstKey: 'firstValue',
secondKey: 'secondValue',
thirdKey: 'thirdValue'
fourthKey: true
};
// Type '"fourthKey"' is not assignable to type 'KeysMatching<ISomeObject, string>'.(2322)
let otherKey: KeysMatching<SomeOtherObject, string> = 'fourthKey';
let fourthValue = someOtherObject[otherKey];
원인
인덱싱 시 유형만 사용할 수 있습니다. 즉, 변수를 참조하기 위해 const를 사용할 수 없습니다.
예
type Person = { age: number; name: string; alive: boolean };
const key = "age";
type Age = Person[key];
결과
Type 'any' cannot be used as an index type.
솔루션
활자를 사용하여 소품을 참조하다
예
type key = "age";
type Age = Person[key];
결과
type Age = number
언급URL : https://stackoverflow.com/questions/32968332/how-do-i-prevent-the-error-index-signature-of-object-type-implicitly-has-an-an
'programing' 카테고리의 다른 글
.ajax() 호출의 데이터에 대한 jQuery .find()가 div 대신 "[객체]"를 반환합니다. (0) | 2023.02.22 |
---|---|
JS 가져오기, 응답 시 헤더를 가져오지 않음 (0) | 2023.02.22 |
create-module-app, 설치 오류("명령어를 찾을 수 없음") (0) | 2023.02.22 |
Spring Boot Dev Tools 프로덕션에서 전원을 끄시겠습니까? (0) | 2023.02.22 |
Angular로부터 해결된 약속을 반환하는 방법$q를 사용하는 JS 서비스? (0) | 2023.02.22 |