Vue模板中ListItem的controlListType类型为何一直是unknown?

vue模板类型缩小

这是我的类型文件,但是有个问题,为什么ListItem下的controlListType类型缩小不了,一直是unknow,就很奇怪image.png,用模板也是这样,我不知道是不是我想法有问题还是怎么样,或者说我需要怎么改进

declare interface ControlType {
    input: {
        config: {
            placeholder?: string;
            rows?: number;
            maxLength?: number;
        };
        check?: {
            type: string;
            message: string;
        };
    };
    select: {
        config: {
            placeholder?: string;
            options?: Array<object>;
            mode?: string;
            lableKey: string;
            valueKey: string;
        };
        check?: {
            type: string;
            message: string;
        };
    };
    radio: {
        config: {
            options?: Array<object>;
            name: string;
        };
        check?: {
            type: string;
            message: string;
        };
    };
    date: {
        config: {};
        check: {};
    };
    dateRange: {};
}

declare type ControlListType<K extends keyof ControlType> = {
    type: K;
    config: ControlType[K]["config"];
    check?: ControlType[K]["check"];
};

declare type displayStyleType = {
    backgroundColor?: string;
    color?: string;
    border?: string;
};
type width = 50 | 100;
declare interface ListItem {
    id: string | number; // 字段id
    filedName: string; // 字段名称
    value?: string | (() => string) | ""; // 显示字段,如果是对象结构,展示需要层级,或者函数,函数用于处理多层级数据或者数组或者格式化数据
    // value返回值提供样式修改,如果value是个函数,displayStyle 失效,需要在此返回值中配置样式可以 直接返回dom结构,对于dom的class或者id,提供额外的style插入。如果复杂的话后续考虑返回jsx,对jsx进行编译
    name: string; // 展示名称
    displayStyle?: displayStyleType; // 列表显示样式,默认显示文本或者提供配置,背景色和文本颜色,只有value是 string 的时候生效
    controlListType: ControlListType<keyof ControlType>; // 控件列表,提供配置、校验、等一些特有控件的私有配置 ,这个只提供一些常规配置,有其他需求的通过 code 编码,
    width?: width; // 展示列表宽度,默认一半
    deploy: {
        isSearch: boolean; // 是否查询字段
        isAdd: boolean; // 是否新增
        isEdit: boolean; // 是否编辑
    };
}
阅读 575
avatarAI BotBETA

这个问题可能是由于 TypeScript 在推断泛型类型时遇到了困难,导致 controlListType 的类型被推断为 unknown

在 TypeScript 中,当你使用泛型时,你需要确保 TypeScript 能够准确地推断出泛型的类型。在你提供的代码示例中,controlListType 的类型是基于 ControlType 的键来确定的,但是 TypeScript 可能无法直接从 ListItem 的定义中推断出 controlListType 的确切类型。

要解决这个问题,你可以尝试以下几种方法:

  1. 显式指定泛型类型:在创建 ListItem 实例时,显式指定 controlListType 的泛型类型。例如:
const item: ListItem = {
  id: '1',
  filedName: 'fieldName',
  value: 'value',
  name: 'Name',
  controlListType: {
    type: 'input',
    config: {
      placeholder: 'Enter text',
    },
  } as ControlListType<'input'>, // 显式指定泛型类型
  width: 50,
  deploy: {
    isSearch: true,
    isAdd: true,
    isEdit: true,
  },
};
  1. 使用类型断言:如果你确定 controlListType 的类型,但 TypeScript 无法推断它,你可以使用类型断言来告诉 TypeScript 你知道这个类型是什么。但请注意,这种方法可能会隐藏类型错误,因此应谨慎使用。
const item: ListItem = {
  // ... 其他字段
  controlListType: {
    type: 'input',
    config: {
      placeholder: 'Enter text',
    },
  } as any as ControlListType<keyof ControlType>, // 使用类型断言
  // ... 其他字段
};
  1. 改进类型定义:如果可能的话,尝试改进你的类型定义,使其更容易被 TypeScript 推断。这可能涉及到重新组织你的类型或添加更多的类型信息。

最后,请注意,如果 controlListType 的类型确实应该是 unknown(即,你希望它可以是 ControlType 中任何键的类型),那么你可能需要重新考虑你的类型设计或使用方式。在这种情况下,你可能需要在使用 controlListType 时进行额外的类型检查或断言。

1 个回答

代码是不是没全,看上面的类型里面 controlListType.config 也没type这个字段嗯


要收窄的话, ControlListType 要这么写, 显式地声明出type的值

type ControlListType = {
    type: 'input',
    config: ...,
    check: ...
} | {
    type: 'select',
    config: ...,
    check: ...
}

或者写个类型做下转换:

type Magic<T extends Record<string, any>, K = keyof T> = K extends keyof T
  ? {
    type: K;
    config: T[K]['config'];
    check: T[K]['check'];
  } : never

type ControlListType = Magic<ControlType>
推荐问题
logo
Microsoft
子站问答
访问
宣传栏