当前位置: 首页 > 知识库问答 >
问题:

在Typescript函数中可以有可选的非结构化参数吗?

燕永昌
2023-03-14

我想编写一个函数,它接受一个对象参数,在函数签名中使用解构,并且该参数是可选的:

myFunction({opt1, opt2}?: {opt1?: boolean, opt2?: boolean})

但是,TypeScript不允许我(绑定模式参数在实现签名中不能是可选的。)。

如果我不破坏结构,我当然可以做到:

myFunction(options?: {opt1?: boolean, opt2?: boolean}) {
  const opt1 = options.opt1;
  const opt2 = options.opt1;
  ...

看起来这些应该是一样的,但是上面的例子是不允许的。

我想使用一个去结构化的语法(1)因为它存在,并且是一个很好的语法,并且上面的两个函数应该表现相同似乎是很自然的,并且(2)因为我还想要一个简洁的方法来指定默认值:

myFunction({opt1, opt2 = true}?: {opt1?: boolean, opt2?: boolean})

在不进行分解的情况下,我必须在函数的实现中隐藏这些默认值,或者有一个参数,它实际上是一个具有构造函数的类。。。

共有3个答案

王俊哲
2023-03-14

这是最好的方法,如果你想混合可选和必需的参数,但有一个导出类型,其中所有的值都是必需的/非空:

export function newCar(args: {
    year?: number
    make?: string
    model: string
    owner: [string, string]
}) {
    const defaults = {
        year: 1999,
        make: "toyota",
    }
    return { ...defaults, ...args }
    // to get a Readonly<Car>:
    // return Object.freeze(args)
}

export type Car = ReturnType<typeof newCar>

const c = newCar({ model: "corolla", owner: ["Gorg", "Blafson"] })

export function print(c: Car) {
    console.log(`${c.owner}'s gorgeous ${c.year} ${c.model} from ${c.make}`)
}
柳羽
2023-03-14

如果没有作为参数给定的对象,则无法分解结构。因此,在parmas中使用一个默认对象,如前一篇文章所述:

type Options = { opt1?: boolean; opt2?: boolean; }

function myFunction({ opt1, opt2 }: Options = {}) {
    console.log(opt2, opt1);
}

myFunction() // undefined,  undefined 
myFunction({opt1: false}); // undefined,  false 
myFunction({opt2: true}); // true,  undefined

我想补充的是,当以下两个条件成立时,参数中的析构模式增加了最多的值:

  • 期权数量可能会发生变化
  • 函数的API可能会发生更改。i、 e.功能参数可能会发生变化

基本上,析构化使您更具灵活性,因为您可以添加任意多的选项,只需对函数的API进行最小的更改。

但是,更基本的版本会更简单:

// If the function is not likely to change often just keep it basic:
function myFunctionBasic( opt1? :boolean, opt2?: boolean ) {
    console.log(opt2, opt1);
}
岳泉
2023-03-14

请改用默认参数:

function myFunction({ opt1, opt2 = true }: { opt1?: boolean; opt2?: boolean; } = {}) {
    console.log(opt2);
}

myFunction(); // outputs: true

这是必要的,为了不破坏结构未定义的

function myFunction({ opt1, opt2 }) {
}
    
// Uncaught TypeError: Cannot destructure property `opt1` of 'undefined' or 'null'.
myFunction();
 类似资料:
  • 我正在用TypeScript编写Jest测试,我想为如下函数创建一个强类型模拟: 请注意,回调是可选的。如果我用要强制转换模拟函数。。。 ...试着这样使用它: ... 我得到TS错误2345: 类型参数(选项:DownloadOptions,回调:(DownloadId: number)= 参数“callback”和“callback”的类型不兼容。 键入“((下载ID:编号)= 类型“未定义”

  • 问题内容: 是否可以直接声明Flask URL可选参数? 目前,我正在按照以下方式进行: 我如何直接说这是可选的? 问题答案: 另一种方法是写 但是我想你想编写一条路由并将其标记为可选?如果是这样,我认为不可能。

  • 但是,如果Terminal中没有提供,我不知道如何(或者是否能够)为其设置默认值。像这样简单的东西不起作用。这里的一个解决方案是根据的内容或大小在函数中设置变量。但我不知道有没有更好的办法做到这一点。 因此,我正在寻找一种方法来使用来自终端的参数调用一个函数,其中需要一个数字(在本例中为2),而其余的是可选的,并设置为默认值。

  • 是否可以直接声明一个烧瓶URL可选参数? 目前,我正在按照以下方式进行: 我怎么能直接说是可选的?

  • 在TypeScript中,我可以将函数的一个参数声明为类型函数。是否有一种“类型安全”的方式来完成这件事,而这是我所缺少的?例如,考虑以下内容: save回调不是类型安全的,我给它一个回调函数,其中函数的参数是一个字符串,但我传递给它一个数字,并且编译时没有错误。我可以在保存类型安全函数中设置结果参数吗? TL;DR版本:在TypeScript中是否存在与.NET委托等价物?

  • 问题内容: 构造函数可以私有吗?私有构造函数有什么用? 问题答案: 是的,构造函数可以是私有的。有不同的用途。一种这样的用法是用于单例设计反模式,我建议你不要使用它。另一个更合理的用法是委派构造函数。你可以让一个构造函数接受很多不同的选项,而这些选项实际上是实现细节,因此你将其设为私有,但是其余的构造函数将委托给它。 作为委派构造函数的示例,以下类允许你保存值和类型,但仅允许你对类型的子集进行保存