【发布时间】:2022-07-31 18:09:04
【问题描述】:
我在使用身份函数时遇到了非常奇怪的行为。我正在编写一个带有模式的向导系统(附件是一个非常简化版本的游乐场链接),并使用受限标识函数进行推理。
问题出现在我使用以下任一属性时无法推断的属性之一:
- 当标识函数的返回值使用
return关键字(而不是用括号括起来的单行返回)时。 或 - 在标识函数中声明可选参数时。该参数在标识函数的类型定义中声明,并且在使用
Parameters<typeof myFunction>时,无论是在声明参数还是未声明参数时,都可以正确推断。
这两个问题对我来说都非常奇怪,这意味着我要么遗漏了一些非常基本的东西,要么发现了 2 个罕见的错误。
这在所有可用的 Playground 版本(试用到 3.3.3)和 4.8 中都重现。
Playground link with relevant code
在操场上查看代码示例可能更好,但是:
类型声明:
type Schema = Record<string, unknown> // modified from original for the sake of the example, if it doesn't make sense
type StepFunction<
TSchema extends Schema = Schema,
> = (anything: unknown) => {
readonly schema: TSchema
readonly toAnswers?: (keys: keyof TSchema) => unknown
}
function step<TSchema extends Schema = Schema>(
stepVal: StepFunction<TSchema>,
): StepFunction<TSchema> {
return stepVal
}
示例: 注意所有函数的返回对象都是一样的!区别在于:
- 我们是否使用
return关键字 (?!?!) - 我们是否有
step函数的参数。不是说如果我做Parameters<typeof myStepValue>,即使参数丢失,它也会被正确推断(!)
// WORKS: `keys` is inferred based on the `schema`
// - no argument for `step` function
// - no `return` keyword
const workingExample = step(() => ({
schema: {
attribute: 'anything',
},
toAnswers: keys => {
// RESULT: `keys` inferred successfully as `attribute`
type Test = string extends typeof keys ? never : 'true'
const test: Test = 'true'
return { test }
},
}))
// FAILS: `keys` is not inferred based on the `schema`
// - has argument for `step` function
const nonWorkingA = step(_something => ({
schema: {
attribute: 'anything',
},
toAnswers: keys => {
// RESULT: `keys` failed to inferred hence defaults to `string`
type Test = string extends typeof keys ? never : 'true'
const test: Test = 'true'
return { test }
},
}))
// FAILS: `keys` is not inferred based on the `schema`
// - has `return` keyword rather than a "single-return" return with parentheses
const nonWorkingB = step(() => {
return {
schema: {
attribute: 'anything',
},
toAnswers: keys => {
// RESULT: `keys` failed to inferred hence defaults to `string`
type Test = string extends typeof keys ? never : 'true'
const test: Test = 'true'
return { test }
},
}
})
【问题讨论】:
标签: typescript types return arguments inference