我正在编写一组工厂函数,每个工厂函数将返回更大的整体对象的一部分。由于它是一种复杂的类型,因此我希望能够使用智能感知来帮助我编写这些功能。
我不知道使用哪种返回类型来注释函数,以确保获得智能/自动完成功能。到目前为止,我已经尝试了三件事。对于这些示例,您可以假设FooType
被定义为:
interface FooType {
prop1: boolean;
prop2: boolean;
...
}
我可以使用类型推断来自动确定函数的类型,但是然后我没有任何类型推断。
function PartialFooMaker1() {
return {
prop1: true,
// I want autocomplete in here
}
}
function PartialFooMaker2() {
return {
prop2: true,
// I also want autocomplete in here
}
}
export const Foo: FooType = Object.assign({}, PartialFooMaker1(),PartialFooMaker2());
我可以将完整类型指定为函数返回类型,但是如果我省略一些属性,那将(正确)触发编译错误。
function PartialFooMaker1(): FooType {
return {
prop1: true,
// I have autocomplete, but TS complains about the lack of prop2
}
}
function PartialFooMaker2(): FooType {
return {
prop2: true,
// I have autocomplete, but TS complains about the lack of prop1
}
}
export const Foo: FooType = Object.assign({}, PartialFooMaker1(),PartialFooMaker2());
我可以将完整类型指定为函数返回类型,但是如果我省略一些属性,那将(正确)触发编译错误。
function PartialFooMaker1(): Partial<FooType> {
return {
prop1: true,
// I have autocomplete! :)
}
}
function PartialFooMaker2(): Partial<FooType> {
return {
prop2: true,
// I have autocomplete! :)
}
}
// the compile error is now here - TS doesn't know that prop1 and prop2 are present
export const Foo: FooType = Object.assign({}, PartialFooMaker1(),PartialFooMaker2());
我还考虑过将FooType拆分为定义明确的子类型,然后与并集类型重新组合,但是实际上它是一个复杂的派生类型,因此对我来说很难拆分。
还有什么我可以尝试的吗?
答案 0 :(得分:0)
如果可以(合理)使用Pick
:
interface NamePart { first: string; last: string }
interface AgePart { age: number; }
interface FooType extends NamePart, AgePart
{
oneMoreThing: string;
}
function PartialFooMaker1(): Pick<FooType, keyof NamePart | "oneMoreThing">
{
return {
first: "Steve",
last: "Stevenson",
oneMoreThing: "!",
}
}
function PartialFooMaker2(): Pick<FooType, keyof AgePart>
{
return {
age: 42
}
}
export const Foo: FooType = { ...PartialFooMaker1(), ...PartialFooMaker2() };
第一部分将具有解析的类型Pick<FooType, "first" | "last" | "oneMoreThing">
,该类型与Pick<FooType, "age">
正确组合以形成FooType
的完整实例。
可以从类型安全的文字和keyof
表达式中合并键。
答案 1 :(得分:0)
Partial
表示共有零个或多个属性。您想要的是Pick
:
function PartialFooMaker1(): Pick<FooType, 'prop1'> {
return {
prop1: true,
// I want autocomplete in here
};
}
function PartialFooMaker2(): Pick<FooType, 'prop2'> {
return {
prop2: true,
// I also want autocomplete in here
};
}
使用Pick
将要求您提供要预先选择的属性,但是这将为您提供IntelliSense。
另一种选择是告诉TypeScript每个工厂函数都返回一个FooType
。
type Slice<T extends object> = { [P in keyof T]: Pick<T, P> }[keyof T];
type FooFactory = () => Slice<FooType>;
const PartialFooMaker3: FooFactory = () => {
return {
prop1: false,
};
};
这不需要显式的返回类型,但是推断的类型将始终是FooType
的 a 切片,而不是{{1}的 the 切片}您实际上正在返回。这就是为什么我建议采用第一方法。如果您未说明所需的返回类型,则IntelliSense不会建议您返回什么。