TS2322를 수정하는 방법: "다른 유형의 구속조건 'object'로 인스턴스화할 수 있습니다."
A의 재귀 유형에 유형 검사 오류가 있습니다.
react-jss style 객체에 활자를 쓰려고 합니다.
type StylesFn<P extends object> = (
props: P
) => CSS.Properties<JssValue<P>> | number | string;
type JssValue<P extends object> =
| string
| number
| Array<string | number>
| StylesFn<P>;
// @ts-ignore
interface StylesObject<K extends string = any, P extends object = {}>
extends Styles {
[x: string]: CSS.Properties<JssValue<P>> | Styles<K, P>;
}
export type Styles<K extends string = any, P extends object = {}> = {
[x in K]: CSS.Properties<JssValue<P>> | StylesObject<any, P> | StylesFn<P>
};
정상적으로 동작하지만, 타이프 스크립트가 에러를 쓴다. 용 i i i i를 쓴다.@ts-ignore
않다.
ERROR 24:11 typecheck Interface 'StylesObject<K, P>' incorrectly extends interface 'Styles<any, {}>'.
Index signatures are incompatible.
Type 'Properties<JssValue<P>> | Styles<K, P>' is not assignable to type 'StylesFn<{}> | Properties<JssValue<{}>> | StylesObject<any, {}>'.
Type 'Properties<JssValue<P>>' is not assignable to type 'StylesFn<{}> | Properties<JssValue<{}>> | StylesObject<any, {}>'.
Type 'Properties<JssValue<P>>' is not assignable to type 'Properties<JssValue<{}>>'.
Type 'JssValue<P>' is not assignable to type 'JssValue<{}>'.
Type 'StylesFn<P>' is not assignable to type 'JssValue<{}>'.
Type 'StylesFn<P>' is not assignable to type 'StylesFn<{}>'.
Type '{}' is not assignable to type 'P'.
'{}' is assignable to the constraint of type 'P', but 'P' could be instantiated with a different subtype of constraint 'object'.
이 오류는 무엇을 의미합니까?
@fetz great answer를 보완합니다.
단답
TLDR: 이런 종류의 오류 메시지에는 두 가지 일반적인 원인이 있습니다.첫 번째 작업을 수행 중입니다(아래 참조).텍스트와 함께 이 에러 메시지가 무엇을 전하고 싶은지 자세히 설명합니다.
원인 1: 타이프스크립트에서는 구체적인 인스턴스를 타입 파라미터에 할당할 수 없습니다.'문제'와 '해결된 문제'의 예를 볼 수 있으므로 차이를 비교하고 어떤 변화가 있는지 확인할 수 있습니다.
문제
const func1 = <A extends string>(a: A = 'foo') => `hello!` // Error!
const func2 = <A extends string>(a: A) => {
//stuff
a = `foo` // Error!
//stuff
}
솔루션
const func1 = <A extends string>(a: A) => `hello!` // ok
const func2 = <A extends string>(a: A) => { //ok
//stuff
//stuff
}
참고 항목: TS Playground
원인 2: 코드에서 다음 오류가 발생하지 않습니다.이러한 에러 메세지가 표시되는 것도 정상적인 상황입니다.이 작업은 피해야 합니다.
을 Type Parameter
클래스, 타입 또는 인터페이스로 지정합니다.
아래 코드의 복잡성으로 인해 혼란스러워하지 않도록 주의해 주시기 바랍니다.단, 알파벳 'A'를 제거하면 문제가 어떻게 해결되는지에만 집중해 주시기 바랍니다.
문제:
type Foo<A> = {
//look the above 'A' is conflicting with the below 'A'
map: <A,B>(f: (_: A) => B) => Foo<B>
}
const makeFoo = <A>(a: A): Foo<A> => ({
map: f => makeFoo(f(a)) //error!
})
해결책:
type Foo<A> = {
// conflict removed
map: <B>(f: (_: A) => B) => Foo<B>
}
const makeFoo = <A>(a: A): Foo<A> => ({
map: f => makeFoo(f(a)) //ok
})
참고 항목: TS Playground
장황한 답변
에러 메시지에 대해서
아래 오류 메시지의 각 요소를 분해합니다.
Type '{}' is not assignable to type 'P'.
'{}' is assignable to the constraint of type 'P', but 'P' could be
instantiated with a different subtype of constraint'object'
에 {}
null 또는 정의되지 않은 것을 제외한 모든 것을 할당할 수 있는 유형입니다.예를 들어 다음과 같습니다.
type A = {}
const a0: A = undefined // error
const a1: A = null // error
const a2: A = 2 // ok
const a3: A = 'hello world' //ok
const a4: A = { foo: 'bar' } //ok
// and so on...
참고 항목: TS Playground
★★에 is not assignable
할당이란 특정 유형의 변수를 특정 인스턴스에 대응시키는 것입니다.인스턴스 유형이 일치하지 않으면 오류가 발생합니다.예를 들어 다음과 같습니다.
// type string is not assignable to type number
const a: number = 'hello world' //error
// type number is assinable to type number
const b: number = 2 // ok
different subtype
두 가지 유형은 동일합니다. 즉, 서로 관련된 세부 정보를 추가하거나 삭제하지 않는 경우입니다.
두 가지 유형이 다릅니다. 동일하지 않은 경우입니다.
Type은 type의 하위 유형입니다.A
기존 상세정보를 삭제하지 않고 상세정보를 추가합니다.S
.
type과 type은 type의 서브타입이 다릅니다.A
★★★★★★★★★★★★★★★★★」B
는 의 입니다.S
A
★★★★★★★★★★★★★★★★★」B
른른른타타타다다 다음과 같습니다.A
★★★★★★★★★★★★★★★★★」B
에 의해 됩니다.S
단, 같은 상세 내용을 추가하지는 않습니다.
예:다음 코드에서는 다음 문장이 모두 참입니다.
- A와 D는 동일한 유형입니다.
- B는 A의 서브타입이다.
- E는 A의 서브타입이 아닙니다.
- B와 C는 A의 다른 서브타입이다.
type A = { readonly 0: '0'}
type B = { readonly 0: '0', readonly foo: 'foo'}
type C = { readonly 0: '0', readonly bar: 'bar'}
type D = { readonly 0: '0'}
type E = { readonly 1: '1', readonly bar: 'bar'}
type A = number
type B = 2
type C = 7
type D = number
type E = `hello world`
type A = boolean
type B = true
type C = false
type D = boolean
type E = number
메모: 구조 유형
에서 TS의 되었을 때
type
" " " 입니다.type A = { foo: 'Bar' }
다음을 읽어보십시오.type alias는 type structure를 가리키고 있습니다.은 다음과 같습니다.
type [type_alias_name] = [type_structure]
.할 수 것은, 「Typescript type 」입니다.
[type_structure]
and and and and and and and and and and and and[type_alias_name]
, TS에서는 . 、 TS 서 、 TS 서 서 、 TS 음 에 、 TS 음 、 TS 음 . 。type A = { foo: 'bar }
★★★★★★★★★★★★★★★★★」type B = { foo: 'bar' }
자세한 내용은 공식 문서를 참조하십시오.
★★에 constraint of type
Type Constraint는 단순히 'extends' 키워드의 오른쪽에 붙이는 것입니다.다음 예에서는Type Constraint
입니다.비아냥거리다.
const func = <A extends B>(a: A) => `hello!`
확인: 유형 제약 조건 'B'는
에러가 발생하는 이유
예를 들면 세 가지 케이스를 보여드릴게요.은, 「이것」입니다.Type Constraint
않습니다
은, 「 」의 은, 「 」입니다.Type Constraint
Type Parameter
에는 다른 서브타입은 포함되지 않습니다.어디 보자:
지정:
type Foo = { readonly 0: '0'}
type SubType = { readonly 0: '0', readonly a: 'a'}
type DiffSubType = { readonly 0: '0', readonly b: 'b'}
const foo: Foo = { 0: '0'}
const foo_SubType: SubType = { 0: '0', a: 'a' }
const foo_DiffSubType: DiffSubType = { 0: '0', b: 'b' }
케이스 1: 제한 없음
const func = <A>(a: A) => `hello!`
// call examples
const c0 = func(undefined) // ok
const c1 = func(null) // ok
const c2 = func(() => undefined) // ok
const c3 = func(10) // ok
const c4 = func(`hi`) // ok
const c5 = func({}) //ok
const c6 = func(foo) // ok
const c7 = func(foo_SubType) //ok
const c8 = func(foo_DiffSubType) //ok
케이스 2: 몇 가지 제약 사항
아래에서는 제한은 하위 유형에 영향을 주지 않습니다.
매우 중요: 타이프 스크립트로
Type Constraint
하지 않습니다.
const func = <A extends Foo>(a: A) => `hello!`
// call examples
const c0 = func(undefined) // error
const c1 = func(null) // error
const c2 = func(() => undefined) // error
const c3 = func(10) // error
const c4 = func(`hi`) // error
const c5 = func({}) // error
const c6 = func(foo) // ok
const c7 = func(foo_SubType) // ok <-- Allowed
const c8 = func(foo_DiffSubType) // ok <-- Allowed
케이스 3: 제약 강화
const func = <A extends SubType>(a: A) => `hello!`
// call examples
const c0 = func(undefined) // error
const c1 = func(null) // error
const c2 = func(() => undefined) // error
const c3 = func(10) // error
const c4 = func(`hi`) // error
const c5 = func({}) // error
const c6 = func(foo) // error <-- Restricted now
const c7 = func(foo_SubType) // ok <-- Still allowed
const c8 = func(foo_DiffSubType) // error <-- NO MORE ALLOWED !
TS 플레이그라운드를 참조해 주세요.
결론
아래 함수는 다음과 같습니다.
const func = <A extends Foo>(a: A = foo_SubType) => `hello!` //error!
다음 오류 메시지가 나타납니다.
Type 'SubType' is not assignable to type 'A'.
'SubType' is assignable to the constraint of type 'A', but 'A'
could be instantiated with a different subtype of constraint
'Foo'.ts(2322)
는 "Typescript"를하기 때문입니다.A
Foo'의 다른 서브타입으로 함수를 호출하는 것을 제한하는 언어에는 제한이 없습니다.예를 들어, 아래의 모든 함수의 호출은 유효한 것으로 간주됩니다.
const c0 = func(foo) // ok! type 'Foo' will be infered and assigned to 'A'
const c1 = func(foo_SubType) // ok! type 'SubType' will be infered
const c2 = func(foo_DiffSubType) // ok! type 'DiffSubType' will be infered
합니다.Type Parameter
에서는 이 틀렸기 때문입니다.TSType Parameter
는 항상 임의의 다른 서브타입으로 인스턴스화할 수 있습니다.
솔루션:
파라미터에 이는 「알겠습니다」라고 해 주세요.read-only
신신음 음
const func = <A extends Foo>(a: A) => `hello!` //ok!
Type을 입니다. 범용 타입 †P
이 안 되다{}
Type ]그래서 [Generic Type]이래P
는 디폴트값과 경합할 가능성이 있는 특정 타입으로 정의 또는 제한할 수 있습니다.
, 값 「」, 「」가{}
Type Generic Type에서 할 수 수 .P
.
이해하기 쉬운 부울만 사용하여 다른 예를 만들어 보겠습니다.
interface OnlyBoolIdentityInterface<T extends boolean> {
(arg: T): T;
}
function onlyBoolGeneric<T extends boolean>(arg: T = false): T {
return arg;
}
예를 들어 부울보다 구체적인 유형을 정의하는 경우:
type TrueType = true;
그리고 만약 당신이 그 기능을 전문화했다면OnlyBoolIdentityInterface
하다
const onlyTrueIdentity: OnlyBoolIdentityInterface<TrueType> = onlyBoolGeneric;
이 TrueType에 의해 T extends boolean
'''arg: T = false
아니다TrueType
.
이것이 에러가 전달하려고 하는 상황입니다.
그러면 이런 유형의 오류를 어떻게 해결할 수 있을까요?
- 또는 기본값을 삭제합니다.
- 또는 T는 디폴트파라미터의 특수한 유형을 확장해야 합니다.이 예에서는 false입니다.
- 또는 T가 디폴트 파라미터를 수신하는 파라미터에 직접 간섭할 수 있습니다.
이 오류 메시지에 대한 자세한 내용은 이 오류 메시지를 제시한 문제를 참조하십시오.https://github.com/Microsoft/TypeScript/issues/29049
조금 더 간략하게 설명하겠습니다.
에러를 발생시키는 예:
type ObjectWithPropType<T> = {prop: T};
// Mind return type - T
const createCustomObject = <T extends ObjectWithPropType<any>>(prop: any): T => ({ prop });
type CustomObj = ObjectWithProp<string> & { id: string };
const customObj = createCustomObj<CustomObj>('value'); // Invalid
// function will only ever return {prop: T} type.
객체가 항상 인 "Atribute"에만입니다.prop
다른 속성은 없습니다.의 확장ObjectWithPropType
잘못된 유형의 제약이 있음을 나타냅니다.이 예에서는 오브젝트 속성의 실제 경합을 나타내기 위해 단순히 그림으로 사용한 잘못된 접근법입니다.
작성 함수에서 하위 유형을 제한하는 방법:
type StringPropObject = ObjectWithPropType<string>
const createCustomObject = <T>(prop: T extends ObjectWithPropType<infer U> ? U : T): ObjectWithPropType<T> => ({ prop });
const stringObj = createCustomObject<StringPropObject>('test');
이 경우 함수는 인수를 문자열로 해야 합니다.에는 「」만 .prop
속성 및 함수가 필요한 쉐이프를 반환합니다.
@flavio-vilante의 훌륭한 답변을 보완합니다.
그래도 필요한 경우(인수는 생략할 수 있으며 생략할 경우 로 폴백합니다).
const func = <A extends Foo>(a: A = foo_SubType) => `hello!` //error!
시험 가능:
const func = <A extends Foo>(a?: A) => {
const aa = a === undefined ? foo_SubType : a;
return `hello!`;
}
않고 .Foo
대신 직접.
const func = (a: Foo = foo_SubType) => `hello!`
내 경우 일반 유형의 열거형(T extenses enum)을 사용하여 다음과 같은 컴포넌트를 선택하고 싶었다.
export function BasicSelector<T extends string>(props: IProps<T>) {
그리고 "Type 'string' is not assignable to type 'T'" 라는 에러가 발생했습니다.그래서 결국 Type을 적용했습니다.
onChange={(e) => onChange(e.target.value as T)}
언급URL : https://stackoverflow.com/questions/56505560/how-to-fix-ts2322-could-be-instantiated-with-a-different-subtype-of-constraint
'IT' 카테고리의 다른 글
tsconfig의 "target" 및 "module"에 대해 (0) | 2023.02.22 |
---|---|
각진 경우 ng-if angular로 일회성 바인딩? (0) | 2023.02.22 |
워드프레스를 사용해서 입력을 삭제하는 가장 좋은 방법을 알려주시겠어요? (0) | 2023.02.22 |
jQuery 없이 $http로 urlencoded 폼 데이터를 POST하려면 어떻게 해야 합니까? (0) | 2023.02.22 |
Angular 2 변경 감지는 어떻게 작동합니까? (0) | 2023.02.22 |