Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
253 views
in Technique[技术] by (71.8m points)

typescript - Differentiating return type based on argument

I'm trying to type a function that either accepts a string or string[] and returns either a bool or bool[] respectively. I've tried both using generics types and overload but both seem to throw some kind of error:

// generic way
function genericWay<T extends string | string[]>(val: T): T extends string ? boolean : boolean[] {
    if (typeof val === 'string'){
        return true // Type 'true' is not assignable to type 'T extends string ? boolean : boolean[]'
    }
    return [true] // Type 'true[]' is not assignable to type 'T extends string ? boolean : boolean[]'
}

const a1 = overloadWay('bbb')
const a2 = genericWay(['bbb'])
const a3 = genericWay(5333) // should throw error


// overload way
function overloadWay(val: string[]): boolean[]; // This overload signature is not compatible with its implementation signature.
function overloadWay(val: string): boolean {    
    if (typeof val === 'string'){
        return true
    }
    return [true] // Type 'boolean[]' is not assignable to type 'boolean'.
}

const b1 = overloadWay('bbb')
const b2 = overloadWay(['bbb'])
const b3 = overloadWay(5333) // should throw error

ts playground

  1. From the first example - it seems my return type is incorrect?
  2. For the overload way, for some reason it's not picking up on type check to differentiate between the two input types.
question from:https://stackoverflow.com/questions/65896206/differentiating-return-type-based-on-argument

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Since another answer already provides with how to fix the warning in the generic way, which requires explicit type casting, here is how you can use function overloading to achive the same goals.

Your overload way definition is not correct. You need to specify all the overloads before the function and the implementing function should contain all the possible inputs and outputs in its signature. You may resort to any in the implementation, but I do not think that's advisable wherever you can avoid.

Here is the overload way

// overload way
function overloadWay(val: string[]): boolean[];
function overloadWay(val: string): boolean ;
function overloadWay(val: string| string[]): boolean | boolean[] {    
    if (typeof val === 'string'){
        return true
    }
    return [true]
}

// b1 is boolean
const b1 = overloadWay('bbb')

// b2 is boolean[]
const b2 = overloadWay(['bbb'])

// shows error
const b3 = overloadWay(5333) 

TS Playground


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...