Typescript 基于传递的布尔参数的返回类型

Typescript 基于传递的布尔参数的返回类型,typescript,typeorm,typescript-generics,typescript-types,Typescript,Typeorm,Typescript Generics,Typescript Types,我想编写一个执行SQL查询字符串的函数,您可以通过泛型指定期望的类型(字符串、数字、日期、带字符串或数字的对象,但不包括函数、类等)。我的代码是: type Payload = Array<string | number>; type ExpectedObj = Record<string, string | number>; type Options = Partial<{ onlyOne: true | false; columnName: string

我想编写一个执行SQL查询字符串的函数,您可以通过泛型指定期望的类型(字符串、数字、日期、带字符串或数字的对象,但不包括函数、类等)。我的代码是:

type Payload = Array<string | number>;
type ExpectedObj = Record<string, string | number>;
type Options = Partial<{
  onlyOne: true | false;
  columnName: string;
}>;

/**
 * Simple function created to execute SQL queries.
 * @param {String} queryString Required. Query string to execute.
 * @param {Payload} payload Optional. Pass variables into query string.
 * @param {Options} options Optional. Would you like to retrieve only the first record or only the one column?
 * @returns {T} Any object/property.
 */
export const executeQuery = async <T extends string | number | ExpectedObj>(
  queryString: string,
  payload?: Payload,
  options: Options = {},
): Promise<Options["onlyOne"] | Options["columnName"] extends true | string ? T : T[]> => {
  const entityManager: EntityManager = getManager();
  const queryResult = (await entityManager.query(queryString, payload)) as T extends string | number ? {
    [key: string]: T;
  }[] : T[];

  options.onlyOne = !options.columnName ? options.onlyOne : true; 

  // (the error occurs here)
  if (options.onlyOne && options.columnName) {
    return (queryResult[0] ? queryResult[0][options.columnName] : {}) as T;
  } else if (options.onlyOne && !options.columnName) {
    return (queryResult[0] ?? {}) as T;
  } else {
    return queryResult as T[];
  }
};
类型有效载荷=阵列;
类型ExpectedObj=记录;
类型选项=部分;
/**
*创建用于执行SQL查询的简单函数。
*@param{String}查询字符串是必需的。要执行的查询字符串。
*@param{Payload}负载可选。将变量传递到查询字符串中。
*@param{Options}Options可选。您想只检索第一条记录还是只检索一列?
*@返回{T}任何对象/属性。
*/
export const executeQuery=async(
查询字符串:字符串,
有效载荷?:有效载荷,
选项:选项={},
):承诺=>{
常量entityManager:entityManager=getManager();
const queryResult=(wait entityManager.query(queryString,payload))作为T扩展字符串| number{
[键:字符串]:T;
}[]:T[];
options.onlyOne=!options.columnName?options.onlyOne:true;
//(错误发生在此处)
if(options.onlyOne&&options.columnName){
返回(queryResult[0]?queryResult[0][options.columnName]:{})作为T;
}else if(options.onlyOne&&!options.columnName){
返回(queryResult[0]??{})作为T;
}否则{
将查询结果返回为T[];
}
};
用法示例:

/* Returns array of objects */
await executeQuery<{
  fullname: string;
  age: number;
  birthday: string;
}>(SOMETHING_QUERY, [id]);

/* Returns the first record */
await executeQuery<{
  fullname: string;
  age: number;
  birthday: string;
}>(SOMETHING_QUERY, [id], { onlyOne: true });

/* Returns only the 'age' column from the first record found */
await executeQuery<string>(SOMETHING_QUERY, [], {
  onlyOne: true,      // can be skipped if columnName is passed
  columnName: "age",
});
/*返回对象数组*/
等待执行(查询[id]);
/*返回第一条记录*/
等待执行(SOMETHING_QUERY,[id],{onlyOne:true});
/*仅返回找到的第一条记录中的“年龄”列*/
等待执行任务(查询内容,[]{
onlyOne:true,如果传递了columnName,则可以跳过//
专栏名称:“年龄”,
});
不幸的是,我发现了这样的错误:
类型“T”不能分配给类型“T[]”

我不知道为什么。VSCode显示
executeQuery
总是返回
T[]
,但这不是我所期望的。我看到的例子是“https://stackoverflow.com/questions/52817922/typescript-return-type-depending-on-parameter“,但他们没有帮助。我想要的就是让我的功能更灵活


当然,我可以只指定
Promise
,但使用这种方法,我必须在任何地方都指出这一点(例如
const smth:string | string[]=wait executeQuery(…);
或将返回的类型强制转换为某个字符串)。请帮忙。如果您能更正我的代码,我也会很高兴…

嗨!请拿着(你得到了一个徽章!),四处看看,仔细阅读,特别是我还推荐Jon Skeet's和。请将上述问题简化为一个问题,以帮助他人帮助您。但您可能正在寻找。是的,谢谢。我解决了函数重载的问题。