简体   繁体   English

是否可以在 Typescript 中定义非空数组类型?

[英]Is it possible to define a non empty array type in Typescript?

I have a list of numbers that I know is never empty.我有一个我知道永远不会为空的数字列表。 Is it possible to define an array in Typescript that is never empty?是否可以在 Typescript 中定义一个永远不会为空的数组?

I know that it is possible with tuples like [ number, number ] but this will not work as my array can be any size.我知道像[ number, number ]这样的元组是可能的,但这不起作用,因为我的数组可以是任何大小。

I guess what I am looking for is a NonEmptyArray<number> type.我想我正在寻找的是NonEmptyArray<number>类型。

Does it exist?它存在吗? :) :)

A feature request for allowing you to just check array.length > 0 to guard against empty arrays, microsoft/TypeScript#38000 , was declined as being too complex.一项允许您只检查array.length > 0以防止空数组的功能请求microsoft/TypeScript#38000因过于复杂而被拒绝。 Essentially you cannot usually simply check length in TypeScript to convince the compiler about the availability of properties at given numeric keys.本质上,您通常不能简单地在 TypeScript 中检查length来说服编译器关于给定数字键的属性的可用性。

You can define a non-empty array type like this:您可以像这样定义一个非空数组类型:

type NonEmptyArray<T> = [T, ...T[]];

const okay: NonEmptyArray<number> = [1, 2];
const alsoOkay: NonEmptyArray<number> = [1];
const err: NonEmptyArray<number> = []; // error!

This is due to support added in TS 3.0 for rest elements in tuple types .这是因为在 TS 3.0 中添加了对元组类型中剩余元素的支持。 I'm not sure what your use case is... It's probably more annoying to use that type than you expect, though:我不确定你的用例是什么......但是使用这种类型可能比你预期的更烦人:

function needNonEmpty(arr: NonEmptyArray<number>) {}
function needEmpty(arr: []) {}

declare const bar: number[];
needNonEmpty(bar); // error, as expected

if (bar.length > 0) {
    needNonEmpty(bar); // ugh, still error!
}

If you want a length check to work, you'll need to use something like a user-defined type guard function, but it's still annoying to use:如果你想让length检查工作,你需要使用类似用户定义的类型保护函数的东西,但使用它仍然很烦人:

function isNonEmptyArray<T>(arr: T[]): arr is NonEmptyArray<T> {
    return arr.length > 0;
}

if (isNonEmptyArray(bar)) {
    needNonEmpty(bar); // okay
} else {
    needEmpty(bar); // error!! urgh, do you care?        
} 

Anyway hope that helps.无论如何希望有帮助。 Good luck!祝你好运!

我也想知道这个并想出了一个不同的解决方案:

type NonEmptyArray<T> = T[] & { 0: T };

Note for a happy reader.给快乐的读者的注意事项。 None of the above solutions is viable.上述解决方案均不可行。

type NonEmptyArray<T> = T[] & { 0: T }
// type NonEmptyArray<T> = [T, ...T[]] -- same behavior

// ISSUE 1: map does not preserve Non-Emptiness
const ns: NonEmptyArray = [1]
const ns2 = ns.map(n => n) // number[] !!!

// ISSUE 2: length check does not make an array Non-Empty
function expectNonEmpty<T>(ts: NonEmptyArray<T>): any {}

if (ns2.length > 0) {
  expectNonEmpty(ns2) // type error
}

Just FYI, so you know why you'll unlikely to see NonEmptyArray in practice.仅供参考,所以您知道为什么在实践中不太可能看到NonEmptyArray The above replies should have mention this.上面的回复应该有提到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM