如何在TypeScript中强制传递可选参数的同时传递可选参数?

unhi4e5o  于 2022-12-19  发布在  TypeScript
关注(0)|答案(1)|浏览(212)

我正在写一个函数,期望在SubNodeConfig中只接收一个配置。请理解,我可以通过下面的操作使所有配置都是可选的,但我希望将其中一个设置为强制的,例如,可能使用非空Assert操作符!

export interface SubNodeConfig {
    alphaConfig?: AlphaConfig;
    betaConfig?: BetaConfig;
    charlieConfig?: CharlieConfig;
    deltaConfig?: DeltaConfig;
}

export interface MainNode {
    id: number;
    config: SubNodeConfig;
}

我打算使用它的上下文:

const getUpdated = (
    originalNodes: MainNode[],
    updatedConfig: SubNodeConfig 
) => {
    const updatedNodes= [...originalNodes];

    updatedNodes[indexOfNodeToUpdate] = {
        id: 123456,
        config: updatedConfig,
    };

    return updatedNodes;
};

我也试着看了一下TypeScript utility docs,但是我可能错过了一些东西,谢谢。

yyyllmsg

yyyllmsg1#

下面是一个将自索引mapped typeRequiredPick实用程序类型结合使用的解决方案:

type AlphaConfig = { alpha: 'a' };
type BetaConfig = { beta: 'b' };
type CharlieConfig = { charlie: 'c' };
type DeltaConfig = { delta: 'd' };

interface SubNodeConfig {
    alphaConfig?: AlphaConfig;
    betaConfig?: BetaConfig;
    charlieConfig?: CharlieConfig;
    deltaConfig?: DeltaConfig;
}

type RequireOne<T> = {
    [K in keyof T]-?: Required<Pick<T, K>>;
}[keyof T]

const x: RequireOne<SubNodeConfig> = { alphaConfig: { alpha: 'a' } }; // OK
const y: RequireOne<SubNodeConfig> = {
  alphaConfig: { alpha: 'a' },
  betaConfig: { beta: 'b' }
}; // OK
const z: RequireOne<SubNodeConfig> = {}; // Error

Playground链接

相关问题