如何从可选对象参数中获取文字

How to get literals from optional object param

我有以下代码:

const dd = ['a', 'b'] as const;
function cba<T extends readonly string[]>(a: { b: T }) {
  return (1 as any) as typeof a.b[number];
}

const a = cba({ b: dd });
const b = cba({ b: ['a', 's']});

可变a returning 'a' | 'b'类型,可变b returning string类型,这就是我想要的。有什么方法可以使 b 属性 成为可选的,然后 return 高于文字(如果存在)和 string(如果不存在)?这是我正在尝试的:

function cba<T extends readonly string[]>(a: { b?: T }) {
  return (1 as any) as typeof a.b extends 'undefined' ? string : typeof a.b[number];
}

但它 return 在 typeof a.b[number] 部分出现错误,其中包含无法将号码应用于 T | undefined 的信息。我也在尝试 JS 解决方案,以检查 b 属性 是否存在:

function cba<T extends readonly string[]>(a: { b?: T }) {
  const d = a.b;
  if (d) return (1 as any) as typeof d[number];
  else return (1 as any) as string;
}

但它 returning 总是 string | undefined 类型。有什么想法吗?

PS。 (1 as any) 部分对本题不重要。

您可以使用条件类型来执行此操作:

type Values<T extends readonly string[] | undefined> =
    T extends readonly string[] ? T[number] : undefined;

const dd = ['a', 'b'] as const;
function cba<T extends readonly string[] | undefined>(a: { b?: T }) {
  return (1 as unknown) as Values<T>;
}

const a = cba({ b: dd }); // "a" | "b"
const b = cba({ b: ['a', 's']}); // string
const c = cba({}); // string | undefined