页: 1 类型Node
,作为D
,在其NodeDef<N, D>
,因此,每个代码的不动产显然取决于所有节点。 如果这不是你想要的话,那么你就需要找到一种办法,以更具体地为<代码>pl。 D类型论点。 最好能写上<代码>Graph,以便每个财产为union, Nodef<K, D>
foremevery possible</code>,但该联盟的规模与密码中可比较迅速使用的编号
因此,您将希望Graph
,以便自己成为generic ,并作代表的一类论点。 D
每一财产的类型。 因此,应当有<代码>Graph<D>和K
,载于keyof D, 财产的类型应为Nodef<K, D[K]>
。 与此类似:
type Graph<D extends Record<keyof D, Node>> = {
[K in Node & keyof D]: NodeDef<K, D[K]>
};
在技术上可以做到:<代码> D有钥匙不在Node
之内,但因intersection > > with Node
而将这些钥匙排除在结果之外。
现在,你可以给你一个名字,但需要人工(。
const config: Graph<{ a: "b" }> = {
a: {
name: a ,
deps: [ b ],
compute: ({ b, c }) => { // error
// --------> ~
// Property c does not exist on type { b: number; } .
return 2 * b + c.length;
},
},
};
这确实与你一样奏效,但你又被迫写上<条码>{a:“b”}。 如果类型可以简单地描述一般类型的论据,但可以 t。 http://www.un.org/Depts/DGACM/index_french.htm 因此,你可以提供一种称为<条码>的助手功能,即<条码>条码>。
const config = graph({
a: {
name: a ,
deps: [ b ],
compute: ({ b, c }) => { // error
// --------> ~
// Property c does not exist on type { b: number; }
return 2 * b + c.length;
},
},
});
config;
// ^? const config: Graph<{ a: "b" }>
因此,现在的<代码>config 被推定为类型Graph<{a:“b><>>/code>, 仅依据对的论证。 我们现在必须做的是界定<条码>(<>>>>>。
Here s one approach:
const graph = <const D extends Record<keyof D, Node>>(
g: { [K in keyof D]: K extends Node ? NodeDef<K, D[K]> : never }
): Graph<D> => g;
TypeScript generic inference is a little tricky; it is possible to infer D
from a mapped type over the keys of D
(i.e., if it s a homomorphic mapped type, see What does "homomorphic mapped type" mean? for more info). So it has to be in keyof D
and not in Node & keyof D
. So I moved the "and Node
" restriction to the property type, making it the conditional type K extends Node? NodeDef<K, D[K]> : never
. Any key in keyof D
that does not appear in Node
will be mapped to never
, and you ll get an error.
Playground link to code