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

msp*_*sen 10 typescript

我有一个清单,我知道永远不会为空。是否可以在Typescript中定义一个永远不会为空的数组?

我知道像[ number, number ]这样的元组是可能的,但这将无法工作,因为我的数组可以是任何大小。

我想我要找的是一种NonEmptyArray<number>类型。

是否存在?:)

And*_* II 23

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

type NonEmptyArray<T> = T[] & { 0: T };
Run Code Online (Sandbox Code Playgroud)

  • 这种风格的另一个替代方案是`type NonEmpty&lt;T&gt; = T extends Array&lt;infer U&gt; ?U[] &amp; {'0': U} : 从不;`。用法:`const x: NonEmpty&lt;string[]&gt; = ["myString"];`。这将 NonEmpty 部分与 Array 部分分开。 (5认同)
  • 这本质上是[fp-ts](https://github.com/使用的[定义](https://github.com/gcanti/fp-ts/blob/5e5fa6690415ff071a6d30f5c3b2b9c917e90ee6/src/NonEmptyArray.ts#L53) gcanti/fp-ts)。 (5认同)

jca*_*alz 16

是的,您可以这样定义它:

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

const okay: NonEmptyArray<number> = [1, 2];
const alsoOkay: NonEmptyArray<number> = [1];
const err: NonEmptyArray<number> = []; // error!
Run Code Online (Sandbox Code Playgroud)

这是由于TS 3.0中增加了对元组类型的其余元素的支持。我不确定您的用例是什么...使用这种类型可能比您期望的还要烦人,但是:

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!
}

// guess I need to make a user-defined type guard
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?        
} 
Run Code Online (Sandbox Code Playgroud)

无论如何希望能有所帮助。祝好运!

  • 我的用例是这样的:在 T 列表上使用 head() 和 last() 等函数时,它们作为默认返回 T | 不明确的。这意味着我必须进行检查,或者在我知道数组永远不会为空的情况下,我必须进行类型转换。如果我有一个 NonEmptyArray&lt;T&gt; 我的 head 和 last 函数可以总是返回 T 并且既不需要检查也不需要类型转换。 (2认同)

Iva*_*nin 12

给快乐读者的注释。上述解决方案均不可行。

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
}
Run Code Online (Sandbox Code Playgroud)

仅供参考,所以您知道为什么在实践中不太可能看到NonEmptyArray。上面的回复应该都提到了这一点。


Min*_*ork 7

虽然类型[T, ...T[]]涵盖了大多数情况,但它不接受像[...anotherArray, 'element']. 我个人使用如下所示的类型来涵盖更广泛的情况:

export type NonEmptyArray<T> = [T, ...T[]] | [...T[], T] | [T, ...T[], T];
Run Code Online (Sandbox Code Playgroud)