Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
TypeScript条件通用接口作为参数(数组或对象,基于布尔值)_Typescript_Generics_Type Inference_Typescript Generics - Fatal编程技术网

TypeScript条件通用接口作为参数(数组或对象,基于布尔值)

TypeScript条件通用接口作为参数(数组或对象,基于布尔值),typescript,generics,type-inference,typescript-generics,Typescript,Generics,Type Inference,Typescript Generics,我有一个函数,它应该能够接收两个类似类型的参数。取决于props.multi是否为true或false 问题是它仍然允许我通过multi=false传递value=[]。我怎样才能摆脱这个 interface PropsSingle<T> { value: T, multi: false } interface PropsMulti<T> { value: T[], multi: true } function foo<T>

我有一个函数,它应该能够接收两个类似类型的参数。取决于
props.multi
是否为
true
false

问题是它仍然允许我通过
multi=false
传递
value=[]
。我怎样才能摆脱这个

interface PropsSingle<T> {
    value: T,
    multi: false
}

interface PropsMulti<T> {
    value: T[],
    multi: true
}

function foo<T>(props: PropsSingle<T> | PropsMulti<T>) {
    if(props.multi) {
        let arr = props.value // type detection works fine
    } else {
        let obj = props.value // type detection works fine
    }
}

foo({multi: true, value: []}) // works as expected
foo({multi: true, value: {}}) // throws error as expected
foo({multi: false, value: {}}) // works as expected
foo({multi: false, value: []}) // THIS SHOULD THROW AN ERROR
interface PropsSingle{
值:T,
多重:假
}
接口本体{
值:T[],
多:真的
}
函数foo(props:PropsSingle | PropsMulti){
如果(多道具){
让arr=props.value//类型检测工作正常
}否则{
让obj=props.value//类型检测工作正常
}
}
foo({multi:true,value:[]})//按预期工作
foo({multi:true,value:{}})//按预期抛出错误
foo({multi:false,value:{}})//按预期工作
foo({multi:false,value:[]})//这应该引发一个错误
我已经试过
foo(…)
foo(…)

我发现的唯一解决方案/解决方法是:

interface PropsSingle<T> {
    value: T extends any[] ? never : T,
    multi: false
}
interface PropsSingle{
值:T扩展任何[]?从不:T,
多重:假
}
但我觉得这很奇怪


为什么我不能将类型限制在
函数foo

原因很简单,没有任何东西可以阻止
PropsSingle
中的
t
成为
any[]
。没有简单的方法让typescript知道泛型参数不能扩展给定的类型,我们只能指定
t
扩展的内容

您的解决方案应该是可行的,我通常会在函数上添加约束,并在处理此类场景时使用字符串文字类型提供更具暗示性的错误消息:

interface PropsSingle<T> {
    value: T,
    multi: false
}

interface PropsMulti<T> {
    value: T[],
    multi: true
}

type ErrorIf<T, U, TError> = T extends U ? TError : {} 

function foo<T>(props: (PropsSingle<T> & ErrorIf<T, any[], "Argument to PropsSingle can't be []")| PropsMulti<T>) {
    if(props.multi) {
        let arr = props.value // type detection works fine
    } else {
        let obj = props.value // type detection works fine
    }
}

foo({multi: true, value: []}) // works as expected
foo({multi: true, value: {}}) // throws error as expected
foo({multi: false, value: {}}) // works as expected
foo({multi: false, value: []}) // Error Type '{ multi: false; value: undefined[]; }' is not assignable to type '"Argument to PropsSingle can't be []"'.
interface PropsSingle{
值:T,
多重:假
}
接口本体{
值:T[],
多:真的
}
类型ErrorIf=T扩展U?恐怖:{}

函数foo(props:(PropsSingle&ErrorIfThank you:)。我考虑过类似于
foo的东西(props:M扩展为true?PropsSingle:PropsMulti)
或类似的内容。但我无法让它工作。@BenjaminM我认为除非您明确指定M和t,否则这将不起作用,这可能是您想要避免的。我已经多次看到类似的问题,因此,不幸的是,我没有看到更好的解决方案