网站搜索

typescript - 有办法仅在参数中限制联合类型吗?


我正在尝试将一个函数的参数限制为只能是联合类型。

例如:

type UnionType = readonly string[];

const getSelector = <T extends UnionType>(arg: T)=>{
  return (validType: T[number])=>{
    return 'data is '+(!arg.includes(validType) ? "NOT " : '') + "included";
  }
}

const myFunc = getSelector(["opt1", "opt2", "opt3"] as const); // <== should be fine!
myFunc("opt1"); // auto complete is working!

const myFunc2 = getSelector(["optA", "optB", "optC"]);
myFunc2("optA"); // auto complete is NOT working! since the given options are not const.
// how can I RESTRICT the options as const type?

如上例所示,我尝试使用 readonly 关键字来创建扩展类型。我也尝试了 Readonly<string[]>。有很多可能没有意义的尝试,所以这里不分享,但我想知道是否真的有办法使其成为可能。

答案#1

只需升级通用类型:

操场

const getSelector = <T extends string>(arg: T[])=>{
  return (validType: T) =>{
    return 'data is '+(!arg.includes(validType) ? "NOT " : '') + "included";
  }
}

const myFunc = getSelector(['opt1', "opt2", "opt3"] as const); // <== should be fine!
myFunc('opt1'); // auto complete is working!

const myFunc2 = getSelector(["optA", "optB", "optC"]);
myFunc2('optA'); // auto complete is NOT working! since the given options are not const.
// how can I RESTRICT the options as const type?

答案#2

这正是 TypeScript 5 中发布 const 类型参数的使用场景。

只需在类型前添加 const,自动补全就应该开始工作了:

type UnionType = readonly string[];

const getSelector = <const T extends UnionType>(arg: T)=>{
  return (validType: T[number])=>{
    return 'data is '+(!arg.includes(validType) ? "NOT " : '') + "included";
  }
}

const myFunc = getSelector(["opt1", "opt2", "opt3"] as const); // <== should be fine!
myFunc("opt1"); // auto complete is working!

const myFunc2 = getSelector(["optA", "optB", "optC"]);
myFunc2("optA"); // <== should also be fine!
// @ts-expect-error: Remove this line to see the error
myFunc2("optD"); // <== ERROR!

^^看起来语法让 SO 的高亮显示器出错了 ^^

操场