Typescript type guard for array of different types - Stack Overflow

I know for a single variable I can create a typeguard function to determine its type narrowing as follo

I know for a single variable I can create a typeguard function to determine its type narrowing as follows:

function assert<T>(value: T | null | undefined): value is T {
  return value != null;
}

const value: string | null = unknown();
if (assert(value)) {
  // value must be a string
}

But is there a way to do this for an array of unknown length, ideally of potentially different types, i.e.

function assertValues<T>(...values: Array<T | null | undefined>): values is T[] {
  return values.filter(value => value == null).length === 0;
}

const value1: string | null = unknown1();
const value2: number | null = unknown2();

if (assertValues(value1, value2)) {
  // value1 must be a string
  // value2 must be a number
}

The second example gives a syntax error: A type predicate cannot reference a rest parameter, but is there an alternative way of achieving this in just one function?

I know for a single variable I can create a typeguard function to determine its type narrowing as follows:

function assert<T>(value: T | null | undefined): value is T {
  return value != null;
}

const value: string | null = unknown();
if (assert(value)) {
  // value must be a string
}

But is there a way to do this for an array of unknown length, ideally of potentially different types, i.e.

function assertValues<T>(...values: Array<T | null | undefined>): values is T[] {
  return values.filter(value => value == null).length === 0;
}

const value1: string | null = unknown1();
const value2: number | null = unknown2();

if (assertValues(value1, value2)) {
  // value1 must be a string
  // value2 must be a number
}

The second example gives a syntax error: A type predicate cannot reference a rest parameter, but is there an alternative way of achieving this in just one function?

Share Improve this question edited Mar 11 at 9:01 James Jenkinson asked Mar 10 at 14:36 James JenkinsonJames Jenkinson 1,6722 gold badges17 silver badges35 bronze badges 2
  • 2 "The second example gives a syntax error", could you include that in the question? Are you referring to "A type predicate cannot reference a rest parameter."? – DBS Commented Mar 10 at 14:48
  • You can type guard an array, but not a rest parameter, so the best you can get here is something like this playground link, which is necessarily redundant (you need to pack the elements into an array, then unpack them from the same array). Does that fully address the question? If so I'll write a full answer explaining. If not, what am I missing? – jcalz Commented Mar 10 at 14:55
Add a comment  | 

1 Answer 1

Reset to default 0

Given the restriction you could actually return false or the asserted structure like an array or an object. An interesting solution could be using a callback with verified elements.

Playground


function assertValues<const T extends any[]>(...values: T){
  return values.some(value => value == null) ? false as const : values as {[I in keyof T]: T[I] & {}};
}

function assertValues2<T extends object>(values: T){
  return Object.values(values).some(value => value == null) ? false as const : values as {[K in keyof T]: T[K] & {}};
}

function assertValues3<const T extends any[]>(...args: [...T, (...arr: {[I in keyof T]: T[I] & {}}) => any]): boolean {
  const values = args.slice(0, -1);
  const fn = args.at(-1);
  if(values.some(value => value == null)) return false;
  if(typeof fn === 'function'){
    (fn as any)(...values);
  }
  return true;
}

declare const value1: string | null;
declare const value2: number | null;

let arr = assertValues(value1, value2);
if (arr) {
  const [value1, value2] = arr;
}

let obj = assertValues2({value1, value2});
if (obj) {
  obj.value1;
  obj.value2;
}

assertValues3(value1, value2, (value1, value2) =>{
  value1;
  value2;
});


发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744841309a4596571.html

相关推荐

  • Typescript type guard for array of different types - Stack Overflow

    I know for a single variable I can create a typeguard function to determine its type narrowing as follo

    2天前
    80

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信