简体   繁体   English

Typescript - 计算泛型类型工作不正常

[英]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任何帮助将不胜感激

Link to playground 游乐场链接

// 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

Playground link to code 游乐场代码链接

Invalid answer:无效答案:

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

Valid answer:有效答案:

// 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM