我试图在TS中定义一个对象类型,该对象将一个字符串(我们称其为---
all:
children:
dmz1:
hosts:
myamqdev01.company.net:
nodeId: 1
myamqdev02.company.net:
nodeId: 2
mysmxdev01.company.net:
nodeId: 1
mysmxdev02.company.net:
nodeId: 2
intranet:
hosts:
amqintradev01.company.net:
nodeId: 1
amqintradev02.company.net:
nodeId: 2
smxintradev01.company.net:
nodeId: 1
smxintradev02.company.net:
nodeId: 2
amq:
hosts:
myamqdev01.company.net:
myamqdev02.company.net:
amqintradev01.company.net:
amqintradev02.company.net:
smx:
hosts:
mysmxdev01.company.net:
mysmxdev02.company.net:
smxintradev01.company.net:
smxintradev02.company.net:
)映射到一个参数始终为$ # All machines
$ ansible -i dev/ --list-hosts all
hosts (8):
myamqdev01.company.net
myamqdev02.company.net
mysmxdev01.company.net
mysmxdev02.company.net
amqintradev01.company.net
amqintradev02.company.net
smxintradev01.company.net
smxintradev02.company.net
$ # Intranet
$ ansible -i dev/ --list-hosts intranet
hosts (4):
amqintradev01.company.net
amqintradev02.company.net
smxintradev01.company.net
smxintradev02.company.net
$ # all smx machines
$ ansible -i dev/ --list-hosts smx
hosts (4):
mysmxdev01.company.net
mysmxdev02.company.net
smxintradev01.company.net
smxintradev02.company.net
$ # amq machines only on dmz1
$ # 1. Only whith patterns
$ ansible -i dev/ --list-hosts 'amq:&dmz1'
hosts (2):
myamqdev01.company.net
myamqdev02.company.net
$ # 2. Using limit
$ ansible -i dev/ --list-hosts amq -l dmz1
hosts (2):
myamqdev01.company.net
myamqdev02.company.net
的函数。
我目前拥有的一条记录具有一个key
的K和一个值的函数,如下所示:
key
哪个可以正常工作,但是我想看看是否可以通过使TS弄清楚函数中的string
应该仅是它们的const IsCountry: Record<string, (name: string) => boolean> = {
"US": (name) => true,
"Caracas": => (name) => false
}
字符串来进一步缩小范围,以便类型检查器将如果我尝试通过其他任何警告,则会引发警告或错误:
name
在当前设计下,该调用不会出错,因为该函数的参数可以采用任何key
。
谢谢!
答案 0 :(得分:1)
可以使用mapped types。但是我们需要有一个表示可能的键的类型。下面,我创建了字符串类型的并集-winsound.PlaySound
,并且类型变窄,因此仅需使用确切的键来调用函数。
Countries
如果定义静态列表是一个问题,那么我们可以从现有结构创建类型,也许您有一些带有这些国家/地区键的对象。下面是这种结构的示例,可以作为我们的类型蓝图:
type CountryRecord<A extends string> = {
[Key in A]: (x:Key) => boolean // mapped key - function argument needs to match the key
}
// type which defines all countries keys
type Countries = "US" | "Caracas";
const IsCountry: CountryRecord<Countries> = {
"US": (name) => true,
"Caracas": (name) => false
}
IsCountry["US"]("Caracas") // error
IsCountry["US"]("US") // correct
正如@jcalz在注释中正确提到的,可以通过将正确应用该类型的标识函数来实现此效果。考虑:
const Countries = {
"US": "United States of America",
"Caracas": "Caracas"
}
type Countries = keyof typeof Countries; // type created from existing structure
// now the same usage:
const IsCountry: CountryRecord<Countries> = {
"US": (name) => true,
"Caracas": (name) => false
}
让我们解释一下此身份功能的工作原理:
type CountryRecord<T> = { [K in keyof T]: (name: K) => boolean };
const asCountryRecord = <T extends CountryRecord<T>>(t: T) => t; // identity function which applies the wanted type by inferencing the given structure
const IsCountry = asCountryRecord({
"US": (name) => true,
"Caracas": (name) => false
});
const asCountryRecord = <T extends CountryRecord<T>>(t: T) => t;
-T是可分配给CountryRecord的类型,因此实际上它需要具有所需的结构伪代码-<T extends CountryRecord<T>>
{key: key=>bool}
-参数是类型T的事物,因此TS会推断此处给出的结构,T将等于参数中的typeof值。(t: T)
-这意味着该函数不执行任何操作,仅返回相同的数据,这就是为什么我说它仅是运行时的身份。换句话说,=> t
是一种工具,它可以使用自变量的推论来实现通用类型自变量。解决方案与先前的命题相同,但是从参数中推断出类型,而不是静态的现有类型。