TypeScript:固定大小数组的接口

18
有没有一种方法可以在TypeScript中定义固定大小的数组。例如,在函数定义中,我需要能够说
coord: (c:any) => number[]; //how to say it is an array of size 4

我可以像定义哈希映射一样定义接口吗?

//this doesn't work
interface IArray{
  [number]
}

并且还要限制最大长度为4。


1
希望你能够执行 let a: number[2] = [ 0, 1 ] - Rafael
4个回答

22

你可以返回一个元组(tuple)而不是一个数组:

type array_of_4 = [number, number, number, number];

var myFixedLengthArray :array_of_4 = [1,2,3,4];

// the tuple can be used as an array:
console.log(myFixedLengthArray.join(','));

这并不限制数组大小为四,超出第四个元素仍然可以正常工作... - Per Hornshøj-Schierbeck

7

有点尴尬,但可以这样做:

interface SizeFour<T> {
    0: T;
    1: T;
    2: T;
    3: T;
}

function fn(): SizeFour<string> {
    // Need to cast
    return <any>['', '', '', ''];   
}

var x = fn();
var a = x[0]; // a: string
var b = x[4]; // b: any; error if --noImplicitAny

1
谢谢Ryan,但是没有任何限制阻止我们执行var c = x[10]。因此,在边界上没有安全性可言。这是如何可能的,因为接口中未定义10(索引/方法)。 - bsr

4

防止某人在数组边界之外使用索引甚至是C#也无法做到的。例如,防止您执行以下操作:

var index = 123; 
sizeFour[index];

甚至可以向服务器请求索引吗?

简短的答案是,“如果您坚持使用[]”,则没有防止这种情况的声明方式。

您可以始终执行以下操作:

var bar = {
   one : 'something',
   two: 'somethingelse'
   // etc. 
}

接着只需使用 . ,即 bar.one


0

有一种(hacky)方法可以做到这一点。基本上是在内部数组接口中添加一个新的可选元素,即不可能的类型never。但是,如果第三个元素是undefined,那么这种方法就行不通。

下面的代码是使用最新的Typescript v4.3.2

TS playground link

interface ArraySizeOfTwo {
  0: number;
  1: number;
  2?: never;
}

interface ArrayList {
  [index: number]: ArraySizeOfTwo;
}

const myArray: ArrayList = [
  [1, 2],
  [15, 20],
];

// Error: Type 'number' is not assignable to type 'undefined'.
const myArray2: ArrayList = [
  [1, 2, 3],
  [15, 20],
];

// Error: Property '1' is missing in type '[number]' but required in type 'ArraySizeOfTwo'.
const myArray3: ArrayList = [
  [1, 2],
  [15],
];

// Error: Type 'undefined' is not assignable to type 'number'.
const myArray4: ArrayList = [
  [1, 2],
  [15, undefined],
];

// no errors :(
const myArray5: ArrayList = [
  [1, 2],
  [15, 20, undefined],
];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接