我想两个阵法props 的长度必须相同.

但我不知道怎么写.

就像我的代码一样...

// useFoo.ts
interface Props {
  initialMessage: string;
  messageList: string[];
  messageTimeList: number[];
}

function useFoo({ initialMessage, messageList, messageTimeList }: Props) {
  if (messageList.length === messageTimeList.length) {
    console.log('I want to must be same');
  }
}


// SomeComponent.tsx
function SomeComponent() {

  useFoo({ initialMessage: 'hello world', messageList: ['h', 'e', 'l'], messageTimeList: [1, 2] });
  // I want to be this situation call error
}

我想使用下面的代码.

如何在界面中判断两个props 的长度?

推荐答案

如果要在类型系统中跟踪数组长度,可能需要使用tuple types,其中指定了数组元素的确切长度和顺序.因此,string[]可以有任意数量的任意顺序的字符串,但["h", "e", "l"]必须正好有三个元素,它们的值是字符串literals"h""e""l".

假设你想支持messageList的任何长度,那么你就不能真正写出Props作为一个特定的类型;你需要像{messageList: [], messageTimeList: []} | {messageList: [string], messageTimeList: [number]} | {messageList: [string, string], messagetimeList: [number, number]} | ...这样的无限union.相反,你可能希望PropsT中的genericmessageList的类型,然后用tuple mapping来表示messageTimeList应该是与T相同的形状,只是它的元素应该是number而不是string.看起来是这样的:

interface Props<T extends string[]> {
    initialMessage: string;
    messageList: [...T];
    messageTimeList: [...{ [I in keyof T]: number }];
}

注意,我在[... ]中包装了messageListmessageTimeList属性;这是variadic tuple type,我在这里做这件事只是为了给编译器一个提示,让它推断T的元组类型,而不是普通数组类型.

不管怎么说,Props<["h", "e", "l"]>只允许["h", "e", "l"]messageList,但messageTimeList只允许[number, number, number].你不想手动写出Props<["h", "e", "l"]>,幸运的是你不必...您可以将useFoo()写入T中的泛型,并在调用时让编译器为您推断T:

function useFoo<T extends string[]>(
    { initialMessage, messageList, messageTimeList }: Props<T>
) {
    if (messageList.length === messageTimeList.length) {
        console.log('I want to must be same');
    }
}

让我们来测试一下:

useFoo({
    initialMessage: 'hello world',
    messageList: ['h', 'e', 'l'],
    messageTimeList: [1, 2] // error!
    //~~~~~~~~~~~~~ <--
    // Source has 2 element(s) but target requires 3.
});

useFoo({
    initialMessage: "abc",
    messageList: ['a', 'b', 'c'],
    messageTimeList: [1, 2, 3]
}) // okay

看起来不错!

Playground link to code

Typescript相关问答推荐

具有匹配键的通用对象界面

类型脚本如何将嵌套的通用类型展开为父通用类型

角形标题大小写所有单词除外

有没有一种方法可以在保持类型的可选状态的同时更改类型?

在嵌套属性中使用Required

访问继承接口的属性时在html中出错.角形

类型脚本返回的类型包含无意义的泛型类型名称

在HighChats列时间序列图中,十字准线未按预期工作

部分更新类型的类型相等

如果数组使用Reaction-Hook-Form更改,则重新呈现表单

在VSCode中显示eslint错误,但在终端中运行eslint命令时不显示?(Vite,React,TypeScript)

复选框Angular 在Ngfor中的其他块中重复

在TypeScript中扩展重载方法时出现问题

TypeScrip-根据一个参数值验证另一个参数值

界面中数组中的混合类型导致打字错误

TypeScrip:从嵌套的对象值创建新类型

递归生成常量树形 struct 的键控类型

如何使用angular15取消选中位于其他组件中的复选框

如何将对象的字符串文字属性用作同一对象中的键类型

基于参数的 TS 返回类型