根据打字稿官方的Advanced Type部分,我想获得一个如下的自定义类型。
// This is typescript official example of documentation
declare function f<T extends boolean>(x: T): T extends true ? string : number;
let x = f(Math.random() < 0.5) // Type is 'string | number'
// This is what I do
declare function foo<Q, T extends boolean>(x: T): T extends true ? Q : number;
let res = foo<boolean>(true) // failed, expect res is boolean type, but got Compiler error message: Expected 2 type arguments, but got 1
number | boolean
。我的问题来源来自the sample。
我已经通过根据@ ford04解决方案包装另一个函数解决了我的问题
interface CustomAxiosRequestConfig extends AxiosRequestConfig {
XFullResponse?: boolean;
}
interface CustomAxiosResponse<T = any> extends AxiosResponse {
config: CustomAxiosRequestConfig;
}
interface CustomAxiosInstance {
get<T = any, R = CustomAxiosResponse<T>>(
url: string,
config?: CustomAxiosRequestConfig
): Promise<R>;
}
let axios = {} as CustomAxiosInstance
interface data {}
const getUser = function<T extends CustomAxiosRequestConfig>(config: T){
return axios.get<data, T['XFullResponse'] extends true ? data : CustomAxiosResponse<data>>("/getUser", config)
}
// type is Promise<data>
let res1 = getUser({XFullResponse: true})
// type is Promise<CustomAxiosResponse<data>>
let res2 = getUser({XFullResponse: false})
答案 0 :(得分:1)
您的代码段未收到编译错误。但是无论如何,您应该给2个类型参数,然后它会按预期工作:
declare function foo<Q, T extends boolean>(x: T): T extends true ? Q : number;
let res = foo<boolean, true>(true) // res is of type boolean (T extends true)
let res = foo<boolean, false>(false) // res is of type number (T does not extend true)
let res = foo<boolean, boolean>(true) // res is of type number (T does not extends true)
答案 1 :(得分:1)
对于从此类函数获得的类型安全性,可以对两个通用参数使用推断,如下所示:
let res: boolean = foo(true) // this works
let res_other_type: string = foo(true) // this also works
let res_error: boolean = foo(false) // this is an error
请注意,使用函数签名实际上不可能知道foo
实际返回的内容,因此在此处指定类型几乎和从unknown
返回foo
并进行强制转换一样不安全。到boolean
游乐场here。
答案 2 :(得分:0)
我们这里有两个问题
boolean
类型我认为第一个问题是可以理解的,因为当您不提供默认值时,则需要放置参数,您可以理解,由于函数使用两个参数,因此没有默认值意味着两个都需要传递。
第二个问题可能更难以理解,但是您的条件类型会进入两个分支,因为这是distributed in conditional types联合类型的方式。
类型boolean
是联合体true | false
,这意味着您的条件类型将对联合体的每个元素进行两次评估。因此,让我们看看如何评估两个元素的这种结合-true
和false
true extends true ? Q : number
//得到Q false extends true ? Q : number
//获取号码结果是所有联合元素上所有评估的联合,因此从true | false
中得到Q | number
。
希望我能向您描述您面临的问题。我无法为您提供更多帮助,因为我不了解您的目标是什么。