gpt4 book ai didi

javascript - 如何将某些参数映射为可选参数?

转载 作者:搜寻专家 更新时间:2023-10-30 21:49:31 25 4
gpt4 key购买 nike

上下文:

我正在尝试编写一个函数,允许该函数的用户使用没有 typescript 类型断言(只是普通的旧 javascript 语法)来定义特定类型。基本上,我正在尝试编写类似 React 的 PropTypes 的东西,但我想将使用这些“PropTypes”定义的类型映射到可以使用 typescript 强制执行的类型。

也许通过查看代码更容易理解我要做什么。 defineFunction 下面是一个函数,它返回一个函数,该函数接受由“PropTypes”定义的对象。

interface PropType<T> { isOptional: PropType<T | undefined> }
type V<Props> = {[K in keyof Props]: PropType<Props[K]>};
interface PropTypes {
string: PropType<string>,
number: PropType<number>,
bool: PropType<boolean>,
shape: <R>(definer: (types: PropTypes) => V<R>) => PropType<R>
}

// the only purpose of this function is to capture the type and map it appropriately
// it does do anything else
function defineFunction<Props, R>(props: (types: PropTypes) => V<Props>, func: (prop: Props) => R) {
return func;
}

// define a function
const myFunction = defineFunction(
// this is the interface definition that will be mapped
// to the actual required props of the function
types => ({
stringParam: types.string,
optionalNumberParam: types.number.isOptional,
objectParam: types.shape(types => ({
nestedParam: types.string,
}))
}),
// this is the function definition. the type of `props`
// is the result of the mapped type above
props => {
props.objectParam.nestedParam
return props.stringParam;
}
);

// use function
myFunction({
stringParam: '',
optionalNumberParam: 0,
objectParam: {
nestedParam: ''
}
});

这是通过将鼠标悬停在 VS Code 中的类型上找到的 myFunction 的结果类型:

const myFunction: (prop: {
stringParam: string;
optionalNumberParam: number | undefined;
objectParam: {
nestedParam: string;
};
}) => string

问题:

上面的代码有问题--optionalNumberParam 被正确定义为number | undefined 但它实际上不是可选的!

如果我省略了 optionalNumberParam,typescript 编译器就会对我大喊大叫。

enter image description here

有没有办法断言一个类型是可选的,而不仅仅是 T |未定义?


回复cale_b的评论:

Just a thought - have you tried optionalNumberParam?: types.number.isOptional

是的,它是无效的语法:

enter image description here

需要澄清的是,这个defineFunction 应该让用户使用没有 typescript 类型断言来定义类型——相反,一切都应该使用映射类型来推断。 ? 只是 typescript 。我正在尝试编写此函数,以便 - 理论上 - javascript 用户可以定义 proptypes,并且仍然让 typescript 编译器强制执行这些 proptypes。

最佳答案

因此,我能做的最接近的解决方法涉及我提到的双对象文字解决方案:

interface PropType<T> { type: T }

首先我删除了isOptional因为它对你没有好处,其次我用 T 添加了一个属性因为 TypeScript 不一定能区分 PropType<T>PropType<U>如果TU不同,除非它们在结构上不同。我认为您不需要使用 type属性(property)虽然。

然后是一些我没接触过的东西:

type V<Props> = {[K in keyof Props]: PropType<Props[K]>};
interface PropTypes {
string: PropType<string>,
number: PropType<number>,
bool: PropType<boolean>,
shape: <R>(definer: (types: PropTypes) => V<R>) => PropType<R>
}
function defineFunction<Props, R>(props: (types: PropTypes) => V<Props>, func: (prop: Props) => R) {
return func;
}

现在,我正在创建函数 withPartial ,它采用两个类型的参数 RO并返回 R & Partial<O> 类型的值.

function withPartial<R, O>(required: R, optional: O): R & Partial<O> {
return Object.assign({}, required, optional);
}

让我们试试看:

const myFunction = defineFunction(
types => withPartial(
{
stringParam: types.string,
objectParam: types.shape(types => ({
nestedParam: types.string,
}))
},
{
optionalNumberParam: types.number
}
),
props => {
props.objectParam.nestedParam
return props.stringParam;
}
);

请注意我是如何将原始对象文字分成两部分的:一个具有必需属性,另一个具有可选属性,然后使用 withPartial 重新组合它们功能。还要注意 withPartial() 的用户如何不需要使用任何特定于 TypeScript 的符号,我认为这是您的要求之一。

检查 myFunction 的类型给你:

const myFunction: (
prop: {
stringParam: string;
objectParam: {
nestedParam: string;
};
optionalNumberParam?: number;
}
) => string

这就是你想要的。观察:

// use function
myFunction({
stringParam: '',
//optionalNumberParam: 0, // no error
objectParam: {
nestedParam: ''
}
});

希望对您有所帮助;祝你好运!

关于javascript - 如何将某些参数映射为可选参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48080889/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com