Closed
Description
TypeScript Version: 4.2.0-dev.20201127
Search Terms:
- typescript type inference
- typescript type not inferred correctly
- typescript mapped types
Code
interface INodeIO<T = any> {
value: T;
}
type IODefinition = Record<string, INodeIO>;
type IODefinitionValues<D extends IODefinition> = {
[K in keyof D]: D[K] extends INodeIO<infer T> ? T : never;
};
type CalcFunc<I extends IODefinition, O extends IODefinition> = (
inputs: IODefinitionValues<I>
) => IODefinitionValues<O>;
type NodeDefinition<I extends IODefinition, O extends IODefinition> = {
setup(): { inputs: I; outputs: O };
calculate?: CalcFunc<I, O>;
};
function defineNode<I extends IODefinition, O extends IODefinition>(def: NodeDefinition<I, O>) {
return def; // placeholder
}
// T1 is correctly identified as
// T1 = { hello: number; }
type T1 = IODefinitionValues<{ hello: { value: number } }>;
// T2 is identified as (inputs: IODefinitionValues<{ test: { value: number; };}>) => IODefinitionValues<{ ret: { value: boolean; }; }>
type T2 = CalcFunc<{ test: { value: number } }, { ret: { value: boolean } }>;
// This works as expected, Intellisense is working and I get type errors when using the wrong type
const calcFuncTest: T2 = (def) => ({ ret: Boolean(def.test) });
calcFuncTest({ test: 3 });
defineNode({
setup() {
return {
inputs: {
a: { value: 3 },
b: { value: "bar" }
},
outputs: {
c: { value: false },
d: { value: "foo" }
}
};
},
calculate(inputs) {
return {
c: inputs.v, // (1)
d: inputs.a, // (2)
};
}
});
Expected behavior:
(1)
should give an error, sinceinputs.v
does not exist(2)
should give an error, sinceinputs.a
is anumber
, whiled
is astring
Actual behavior:
The code above compiles without errors. Also, Intellisense is not working at the calculate
function inside defineNode
.
Playground Link:
Link
Related Issues: