[英]Typescript - Computed generic type not working well
I'm trying to set a Generic type that will accept 2 parameters and return a function.我正在尝试设置一个将接受 2 个参数并返回 function 的通用类型。
First parameter - The type of the single parameter of the returned function第一个参数 - 返回的单个参数的类型 function
Second Parameter - need to get true if dev wants the returned function parameter to be required.第二个参数 - 如果开发人员希望返回的 function 参数是必需的,则需要为真。
Somehow it's just not working The Val is inferred to string but it still thinks it's not a string不知何故,它只是不工作 Val 被推断为字符串,但它仍然认为它不是字符串
Any help will be appreciated任何帮助将不胜感激
// Mandatory = true for required parameters
export type ValidationFunction<T = unknown, IsMandatory = unknown> =
<Val = IsMandatory extends true ? T : T | undefined>(val: Val) => true | string;
const test: ValidationFunction<string, true> = (val) => { // error!
// ~~~~
// Type 'Val' is not assignable to type 'string | true'.
return val;
};
test('poop')
// Maybe the core of the issue but weirdly it accepts
// any type of parameter I'll pass to it
test(555)
test(true)
test(null)
test({})
The problem is that you are making ValidationFunction<T, M>
itself a generic function with one type parameter Val
which has a default of IsMandatory extends true? T: T | undefined
问题是您正在使
ValidationFunction<T, M>
本身成为一个通用的 function ,它具有一个类型参数Val
,其默认值为IsMandatory extends true? T: T | undefined
IsMandatory extends true? T: T | undefined
IsMandatory extends true? T: T | undefined
. IsMandatory extends true? T: T | undefined
。 But it doesn't look like you intend for it to be generic at all, and even if you did, the type parameter Val
merely defaults to something;但是看起来您根本不打算让它成为通用的,即使您这样做了,类型参数
Val
也只是默认为某些东西; it isn't constrained at all.它根本不受限制。 So
test
accepts and returns a completely unconstrained Val
, which may or may not have anything to do with string
.因此
test
接受并返回一个完全不受约束的Val
,它可能与string
有任何关系也可能没有关系。
If you change the default to a constraint, things start working how you want:如果将默认值更改为约束,事情就会按照你想要的方式开始工作:
export type ValidationFunction<T = unknown, IsMandatory = unknown> =
<Val extends IsMandatory extends true ? T : T | undefined>(val: Val) => true | string;
// ^^^^^^^ <-- constraint, not default
const test: ValidationFunction<string, true> = (val) => {
return val;
}; // okay
test('💩') // okay
test(555) // error
test(true) // error
test(null) // error
test({}) // error
But again, you don't even really want this to be generic.但同样,您甚至不希望它是通用的。 We can just replace
Val
with its constraint and things continue to work how you want:我们可以用它的约束替换
Val
并且事情继续按照你想要的方式工作:
export type ValidationFunction<T = unknown, IsMandatory = unknown> =
(val: IsMandatory extends true ? T : T | undefined) => true | string;
const test: ValidationFunction<string, true> = (val) => {
return val;
}; // okay
test('💩') // okay
test(555) // error
test(true) // error
test(null) // error
test({}) // error
Looks to me like you're saying that your ValidationFunction
for some reason wants to always return string | true
在我看来,您是在说您的
ValidationFunction
出于某种原因想要始终返回string | true
string | true
- why? string | true
- 为什么?
I'd just do it like that我会那样做
export type ValidationFunction<T = unknown, IsMandatory = unknown> =
<Val = IsMandatory extends true ? T : T | undefined>(val: Val) => T;
test('poop') // no warnings
test(555) // warning
test(true) // warning
test(null) // warning
test({}) // warning
test([]) // warning
// Mandatory = true for required parameters
export type ValidationFunction<T = unknown, IsMandatory = unknown> =
(val: IsMandatory extends true ? T : T | undefined) => true | string;
const test: ValidationFunction<string, true> = (val) => {
return val;
};
test('poop')
// Maybe the core of the issue but weirdly it accepts any type of parameter I'll pass to it
test(555)
test(true)
test(null)
test({})
Answer by @jcalz in the comment of the OP's question. @jcalz在 OP 问题的评论中回答。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.