英文:
How to determine return type based on optional parameter's type
问题
以下是翻译好的部分:
我有以下函数:
```ts
export function safeParseInt<T>(value: any, invalid: T = undefined as T): number | T {
if ((value ?? "") === "") return invalid;
const parsed = parseInt(String(value));
if (isNaN(parsed)) return invalid;
return value ? parsed : 0;
}
如您所见,它接受两个参数,如果能够转换,将返回第一个参数转换为整数,否则返回第二个参数。第二个参数是可选的,默认为undefined。
我在类型方面遇到了困难。如果我使用上面的版本:
function test(value: unknown) {
const r = safeParseInt(value);
const x: number | "" = safeParseInt(value);
const y: number | "" = safeParseInt(value, "");
const z: number | "" = safeParseInt(value, undefined);
}
我期望x
和z
会出现错误,但只有z
出现错误。当我悬停在r
上时,我可以看到返回类型是unknown
。
默认值的某些地方搞乱了类型推断。我尝试过返回typeof invalid
,去掉类型提示,让T扩展undefined或扩展unknown。似乎没有什么作用。
希望这对您有所帮助。
<details>
<summary>英文:</summary>
I have the following function:
```ts
export function safeParseInt<T>(value: any, invalid: T = undefined as T): number | T {
if ((value ?? "") === "") return invalid;
const parsed = parseInt(String(value));
if (isNaN(parsed)) return invalid;
return value ? parsed : 0;
}
See this in the typescript playground
As you can see it takes two parameters and returns either the first parameter converted into an integer or the second one if it is unable. The second one is optional and defaults to undefined.
I am having difficulty typing this. If I use the version above:
function test(value: unknown) {
const r = safeParseInt(value);
const x: number | "" = safeParseInt(value);
const y: number | "" = safeParseInt(value, "");
const z: number | "" = safeParseInt(value, undefined);
}
I expected an error on x
and z
, but there is only one on z
. When I hover over r
I can see that the return type is unknown
.
Something about the default value is messing up the inference. I've tried returning typeof invalid
, removing type hints altogether, making T extend undefined or making it extend unknown. Nothing seems to work.
答案1
得分: 1
根据当前函数的声明方式,如果没有提供invalid
参数,它会返回一个unknown
类型的结果。我在这里稍微调整了类型,使它正确。
当然,这仍然无法通过你编写的测试(后面会详细解释为什么)。但是这个函数的类型已经正确了。如果你尝试在不接受相同签名的函数中使用这个输出,编译器会警告你(在playground链接中也添加了这个)。
为什么这个函数有效呢?当你声明一个变量类型,比如const var: <type> = ...
,TypeScript会使用你提供的信息来推断任何泛型类型。
因此,当你调用函数而没有提供invalid
参数时,TypeScript会使用你的类型声明来“猜测”回退参数的类型必须是""
类型。但当你明确传递参数时,它会使用实际参数的类型来推断泛型。
当你使用arguments时,这种推断并不会发生。这就是为什么当我尝试将它传递给一个函数时,TypeScript会抛出错误的原因。
英文:
With the way the function is currently declared it returns an unknown
result if no invalid
argument is provided. I've correctly the typing slightly here
Of course, this still doesn't pass the test you've written (more below on why). But this functions is typed correctly. If you try to use the outputs in a function that doesn't accept the same signature, the compiler will warn you (added this in the playground link as well)
For why this works... When you declare a type with the variable, like const var: <type> = ...
, typescript will use what you've given to infer any generic types.
So when you call the function without the invalid
argument, typescript uses your type declaration to "guess" that the fallback argument must be of type ""
. But when you explicitly pass the argument, it uses the actual arguments type to infer the generic.
This inference doesn't happen when you use the arguments. Which is why the typescript throws an error when I try passing it to a function.
答案2
得分: 1
你应该使用重载。
export function safeParseInt(value: any): number | undefined
export function safeParseInt<T>(value: any, invalid: T): number | T
export function safeParseInt<T>(value: any, invalid: T = undefined as T): number | T {
if ((value ?? "") === "") return invalid;
const parsed = parseInt(String(value));
if (isNaN(parsed)) return invalid;
return parsed;
}
如果未向函数传递invalid
参数,这将显式设置safeParseInt
的返回类型为number | undefined
。
英文:
You should use overloads.
export function safeParseInt(value: any): number | undefined
export function safeParseInt<T>(value: any, invalid: T): number | T
export function safeParseInt<T>(value: any, invalid: T = undefined as T): number | T {
if ((value ?? "") === "") return invalid;
const parsed = parseInt(String(value));
if (isNaN(parsed)) return invalid;
return parsed;
}
This will explicitly set the return type of safeParseInt
to number | undefined
if invalid
is not passed to the function.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论