Typescript 如何修复TS2322:“;可以使用约束的不同子类型';对象'&引用;?
在递归类型中存在类型检查错误 我正在尝试为react jss styles对象编写类型Typescript 如何修复TS2322:“;可以使用约束的不同子类型';对象'&引用;?,typescript,typescript-generics,Typescript,Typescript Generics,在递归类型中存在类型检查错误 我正在尝试为react jss styles对象编写类型 类型样式fn=( 道具:P )=>CSS.Properties | number |字符串; 类型JssValue= |串 |数 |排列 |StylesFn; //@ts忽略 接口样式对象 扩展样式{ [x:string]:CSS.Properties | style; } 导出类型样式={ [x in K]:CSS.Properties|StylesObject|StylesFn }; 它工作正常,但ty
类型样式fn=(
道具:P
)=>CSS.Properties | number |字符串;
类型JssValue
=
|串
|数
|排列
|StylesFn
;
//@ts忽略
接口样式对象
扩展样式{
[x:string]:CSS.Properties | style;
}
导出类型样式={
[x in K]:CSS.Properties|StylesObject|StylesFn
};
它工作正常,但typescript写入错误。我使用了@ts ignore
,但这并不奇怪
错误24:11 typecheck接口“StylesObject”错误地扩展了接口“Styles”。
索引签名不兼容。
类型“Properties | Styles”不可分配给类型“StylesFn | Properties | StylesObject”。
类型“Properties”不可分配给类型“StylesFn | Properties | StylesObject”。
类型“Properties”不可分配给类型“Properties”。
类型“JssValue”不可分配给类型“JssValue”。
类型“StylesFn
”不可分配给类型“JssValue”。
类型“StylesFn
”不可分配给类型“StylesFn”。
类型“{}”不可分配给类型“P”。
“{}”可分配给“P”类型的约束,但“P”可以用约束“object”的不同子类型实例化。
这个错误是什么意思?这个错误是在警告您,您的泛型类型
p
不能分配给{}
,因为泛型类型p
可以是一个更明确的定义,或者限制为一个可能与默认值冲突的特定类型
这意味着值{}
不能满足泛型类型p
可以使用的所有可能类型
让我们创建另一个只包含布尔值的示例,该示例应该更容易理解:
interface OnlyBoolIdentityInterface<T> {
(arg: T): T;
}
function onlyBoolGeneric<T extends boolean>(arg: T = false): T {
return arg;
}
如果专门使用函数OnlyBoolIdentityInterface
,只支持这样的真值:
const onlyTrueIdentity: OnlyBoolIdentityInterface<TrueType> = onlyBoolGeneric;
const onlyTrueIdentity:OnlyBoolIdentityInterface=onlyBoolGeneric;
即使TrueType遵守由T extends boolean
设置的约束,默认值arg:T=false
也不是TrueType
这就是错误试图传达给你的情况
那么,如何修复这类错误呢
有关此错误消息的更多内容,请参阅建议此错误消息的问题。补充@fetzz的精彩答案
简短回答 TLDR此类错误消息有两种常见原因。你正在做第一个(见下文)。除了文本之外,我还详细解释了这个错误消息想要传达什么 原因1:在typescript中,不允许将具体实例分配给类型参数。下面您可以看到“问题”和“问题已解决”的示例,这样您就可以比较两者的差异并查看有哪些变化: 问题
const func1=
原因2:尽管您没有在代码中执行以下错误。这也是出现此类错误消息的正常情况。您应该避免这样做:
在类、类型或接口中重复(错误地)类型参数
不要让下面代码的复杂性迷惑您,我希望您关注的唯一一件事是删除字母“A”如何解决问题:
问题:
输入Foo
长答案
了解错误消息
下面,我将分解以下错误消息的每个元素:
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 TrueType = true;
类型A={}
常数a0:A=未定义//错误
常数a1:A=null//错误
常数a2:A=2//ok
常量a3:A=‘你好,世界’//好的
常量a4:A={foo:'bar'}//ok
//等等。。。
见:
什么是是不可分配的
赋值就是使特定类型的变量对应于特定实例。如果实例的类型不匹配,则会出现错误。例如:
type TrueType = true;
//类型字符串不能分配给类型编号
常量a:number='hello world'//错误
//类型编号与类型编号相同
常数b:number=2//ok
什么是不同的子类型
两种类型是相等的:如果它们不添加或删除彼此相关的详细信息
两种类型是不同的:如果它们不相等
类型A
是类型S
的一个子类型:如果A
添加细节而不删除S
中已经存在的细节
类型A
和类型B
是类型S
的不同子类型:如果A
和B
是S
的子类型,但是A
和B
是不同的类型。换句话说:A
和B
为类型S
添加了细节,但它们没有添加相同的细节
示例:在下面的代码中,以下所有语句均为true:
A和D是相等的类型
B是A的亚型
E不是A的子类型
B和C是A的不同亚型
type A={readonly 0:'0'}
类型B={readonly 0:'0',readonly foo:'foo'}
类型C={readonly 0:'0',readonly bar:'bar'}
类型D={readonly 0:'0'}
类型E={readonly 1:'
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.
type StringPropObject = ObjectWithPropType<string>
const createCustomObject = <T>(prop: T extends ObjectWithPropType<infer U> ? U : T): ObjectWithPropType<T> => ({ prop });
const stringObj = createCustomObject<StringPropObject>('test');