TypeScript [bug] 模板字符串数组与字面量数组类型不兼容

yvt65v4c  于 3个月前  发布在  TypeScript
关注(0)|答案(7)|浏览(42)

TypeScript Version: 2.4.0
Code

// A *self-contained* demonstration of the problem follows...
interface SQLQuery<TResult> {
  __result: TResult;
} 
declare function sql(
  literals: ['SELECT id FROM users'],
  ...placeholders: any[]
): SQLQuery<{id: number}>;

declare function querySync<TResult>(q: SQLQuery<TResult>): Array<TResult>;

const values: Array<{id: number}> = querySync(sql`SELECT id FROM users`);

Expected behavior:

Typescript should see that the input string 'SELECT id FROM users' matches the expected literals of ['SELECT id FROM users'] and use the declared function, allowing me to generate an overloaded version of the sql function for each query.

Actual behavior:

I get the error:
src/index.ts(23,50): error TS2345: Argument of type 'TemplateStringsArray' is not assignable to parameter of type '["SELECT id FROM users"]'.
Property '0' is missing in type 'TemplateStringsArray'.

rkue9o1l

rkue9o1l1#

我认为这取决于#16592

rjzwgtxy

rjzwgtxy2#

实际上,我不知道即使有了我脑海中的想法,这是否会起作用。TemplateStringsArray 实际上是一个 ReadonlyArray<string> ,但你不能将一个 ReadonlyArray 分配给一个可变的 Array 。所以至少你需要编写一些类似

interface MyCustomType extends TemplateStringsArray {
  0: "SELECT id FROM users"
}

的东西。

rqqzpn5f

rqqzpn5f3#

这没问题。无论如何,我都会自动生成这些定义,通过解析代码来查看哪些函数被调用。这对于#16551来说是一个非常有效的解决方法。
然而,目前看来这个方法似乎也不起作用。

p4rjhz4m

p4rjhz4m4#

当将 ReadonlyArray 分配给 Array 时,是否会丢失通用类型信息,这是一个bug吗?

ds97pgxw

ds97pgxw5#

@R00GER,这看起来像是一个单独的bug,它应该有一个自己的问题。

vmpqdwk3

vmpqdwk36#

@DanielRosenwasser ,你能更新一下接下来的步骤吗?

35g0bw71

35g0bw717#

不应该有类型 TemplateStringsArray ,它应该是 const string tuple type ,所以我们可以编写代码:

interface SQL<TSA, VS> {
  texts: TSA;
  values: VS;
}

function sql<TSA extends readonly string[], VS extends any[]>(texts:TSA, ...values: VS): SQL<TSA, VS> {
  return { texts, values };
}

// then
let s: SQL<['select * from person where a=', ' and b=', ''], [number, Date]> = sql`select * from person where a=${1} and b=${new Date()}`;

相关问题