首页 > 解决方案 > 指定应用了某些约束的函数返回类型

问题描述

我是 TypeScript 的新手,正在努力实现某些目标,甚至知道它是否可能。

我希望能够为函数定义一个类型,该类型允许函数的实例设置自己的返回类型,但同时将返回类型限制为键是字符串而值是字符串的对象。

所以泛型类型定义应该允许任何返回类型匹配{ [key: string]: string },但是函数的特定实例可以指定它将返回 { a: 'y', b: 'z' } 然后当使用函数的返回值时,编译器将知道它只有属性 a 和 b 而不仅仅是任何字符串属性。

type obj = {
  name: string,
  doAThing: (path: string) => { [key: string]: string }
}

const anObj: obj = {
  name: 'Alias Fakename',
  doAThing: path => ({ a: 'abc', b: 'xyz' })
}

const result = anObj.functionInstance('abcdef')

在上面的例子doAThinganObj是一个有效的实现genericFunction。但是,当使用result编译器时,它不知道它只有属性ab并且允许使用任何字符串键,例如result.keyWhichDoesntExist不会引发类型错误。

有没有办法在定义doAThinganObj指定其返回类型,以便类型提示将起作用,result同时确保指定的返回类型符合返回类型genericFunction

标签: typescripttypescript-generics

解决方案


您希望使用以下<T>语法使您的函数类型通用:

type GenericFunction<T extends { [key: string]: string }> = (path: string) => T

此函数类型接受T必须具有字符串键名和字符串值的另一种类型,并且无论该类型是什么,这就是函数返回的内容。

然后,您可以使用该类型并锁定它所操作的类型,如下所示:

const functionInstance: GenericFunction<{ a: string, b: string }> =
  (path: string) => ({ a: 'abc', b: 'xyz' })

现在,当您使用该函数时,打字稿知道返回类型是{ a: string, b: string }.

const result = functionInstance('a/path/here')
console.log(result.a) // 'abc'
console.log(result.b) // 'xyz'

游乐场链接

您可以在手册中阅读有关泛型的更多信息。


那么这个函数是接口的一部分吗?

然后你可以使接口本身通用,并做几乎相同的事情:

type MyObj<T extends { [key: string]: string }> = {
  name: string,
  doAThing: (path: string) => T
}

现在MyObj接受T泛型参数,并doAThing()使用它。

你会创建一个MyObj这样的:

const anObj: MyObj<{ a: string, b: string }> = {
  name: 'Alias Fakename',

  // doAThing() return type here is checked to match T
  doAThing: path => ({ a: 'abc', b: 'xyz' }) 
}

现在返回值是强类型的:

const result = anObj.doAThing('abcdef')
console.log(result.a) // works
console.log(result.b) // works

操场


推荐阅读