TypeScript:你能根据函数的参数定义一个返回类型结构吗?

Posted

技术标签:

【中文标题】TypeScript:你能根据函数的参数定义一个返回类型结构吗?【英文标题】:TypeScript: Can you define a return Type structure based on an argument of the function? 【发布时间】:2021-01-10 10:25:09 【问题描述】:

我正在尝试创建一个函数,该函数将接受一个字符串参数并返回一个以该字符串为键的对象。

例如(伪代码): test('bar') => bar: ...

我不确定如何为该函数获取正确的返回类型。

这段代码给了我正确的返回类型,但是 TS 编译器认为我返回的对象与返回类型不匹配?

function test<K extends string>(key: K):[prop in K]: number 
  return  [key]: 6  // error: not assignable

const foo = test<'bar'>('bar')
// foo type: bar: number // return type is good

这样的东西会很好用。但没有给我我正在寻找的强类型返回类型:

function test2<K extends string>(key: K)
  return  [key]: 6 

const foo2 = test2<'bar'>('bar')
// foo2 type: [x: string]: number  // no good

对此的任何帮助将不胜感激!

【问题讨论】:

不进行类型检查的部分原因是,如果K = stringK = 'baz' | 'qux' 怎么办?那么返回的对象与返回类型不匹配。 【参考方案1】:

稍微调整第一次尝试,这似乎有效:

function test<K extends string>(key: K) 
  return  [key]: 6  as [prop in K]: number


const foo = test('bar') //  bar: number 

不过,我觉得必须施放它有点奇怪。

【讨论】:

我真的很想知道如果没有类型转换这是否可能......【参考方案2】:

我不明白你为什么在这里需要泛型,什么反对简单地做

function test(key: string):  [key: string]: number  
  return  [key]: 6 ;

【讨论】:

因为foo 的类型将是: [key: string]: number 而不是具有类型属性bar【参考方案3】:

你可以用扩展类型做很多事情。

就像@SnailCrusher 显示的那样,您可以静态定义返回类型。 还有一种方法可以为返回的 props 动态分配类型:

// this interface defines potential parameters to the methods

interface Tokens 
    foo: number,
    bar: string,




// return one prop in the result object
// this methods only accept keys of the interface Tokens as valid inputs

function test<K extends keyof Tokens>(key: K) 
    switch(key) 
        case 'foo': return  [key]: 0  as [prop in K]: Tokens[K]
        case 'bar': return  [key]: '0'  as [prop in K]: Tokens[K];
    
    return  [key]: undefined  as [prop in K]: Tokens[K]


const bar = test('bar') //  bar: string 
const foo = test('foo') //  foo: number 



// return full interface in the result object
// the given token will be set an all other props will be optional

function test2<K extends keyof Tokens>(key: K) 
    return  [key]: 6  as [prop in K]: Tokens[K] & [P in keyof Tokens]?: Tokens[P];


const bar2 = test2('bar') //  foo?: number; bar: string; 
const foo2 = test2('foo') //  foo: number; bar?: string; 

这也将在有效参数上为您的 IDE 添加丰富的上下文。

您可以在 Typescript 文档中阅读更多内容: https://www.typescriptlang.org/docs/handbook/advanced-types.html#index-types-and-index-signatures

【讨论】:

以上是关于TypeScript:你能根据函数的参数定义一个返回类型结构吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 TypeScript 中定义返回函数的函数类型时出现“找不到参数”

如何使用具有构造函数参数的 TypeScript 类定义 AngularJS 工厂

为没有或许多不同参数类型的函数定义 Typescript 类型

我可以在 Typescript 中重用函数的参数定义吗?

typeScript入门函数与类

构造函数