You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[bug] TemplateStringsArray is incompatible with literal array type #16552
// A *self-contained* demonstration of the problem follows...interfaceSQLQuery<TResult>{__result: TResult;}declarefunctionsql(literals: ['SELECT id FROM users'],
...placeholders: any[]): SQLQuery<{id: number}>;declarefunctionquerySync<TResult>(q: SQLQuery<TResult>): Array<TResult>;constvalues: 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'.
Actually, I don't know if this will work even with the changes I have in mind. TemplateStringsArray is effectively a ReadonlyArray<string> - but you can't assign a ReadonlyArray to a mutable Array. So at the minimum you'd have to write something like
interfaceMyCustomTypeextendsTemplateStringsArray{0: "SELECT id FROM users"}
That would be fine. I'm going to be auto-generating these definitions anyway, by parsing the code to see which functions are called. This would be very much a workaround for #16551.
At the moment, that doesn't seem to work either though.
declarefunctionid<Textendsstring>(list: Array<T>): Array<T>;declarefunctionreadonlyId<Textendsstring>(list: ReadonlyArray<T>): ReadonlyArray<T>;typeLiteralType="foo"|"bar";constarray: Array<LiteralType>=[];constreadonlyArray: ReadonlyArray<LiteralType>=[];constfoo: ReadonlyArray<LiteralType>=id(array);constbar: ReadonlyArray<LiteralType>=readonlyId(array);// ~~~// Type 'ReadonlyArray<string>' is not assignable to type 'ReadonlyArray<LiteralType>'.// Type 'string' is not assignable to type 'LiteralType'.const bar: ReadonlyArray<LiteralType>constbaz: ReadonlyArray<LiteralType>=readonlyId(readonlyArray);
Isn't it a bug that generic type information is being lost when ReadonlyArray is assigned to Array?
There shouldn't be a type TemplateStringsArray, it should be a const string tuple type, so we can write code:
interfaceSQL<TSA,VS>{texts: TSA;values: VS;}functionsql<TSAextendsreadonlystring[],VSextendsany[]>(texts:TSA, ...values: VS): SQL<TSA,VS>{return{ texts, values };}// thenlets: SQL<['select * from person where a=',' and b=',''],[number,Date]>=sql`select * from person where a=${1} and b=${newDate()}`;
Activity
DanielRosenwasser commentedon Jun 16, 2017
I think this is contingent on #16592.
DanielRosenwasser commentedon Jun 16, 2017
Actually, I don't know if this will work even with the changes I have in mind.
TemplateStringsArrayis effectively aReadonlyArray<string>- but you can't assign aReadonlyArrayto a mutableArray. So at the minimum you'd have to write something likeForbesLindesay commentedon Jun 19, 2017
That would be fine. I'm going to be auto-generating these definitions anyway, by parsing the code to see which functions are called. This would be very much a workaround for #16551.
At the moment, that doesn't seem to work either though.
pablobirukov commentedon Jun 21, 2017
Isn't it a bug that generic type information is being lost when
ReadonlyArrayis assigned toArray?ForbesLindesay commentedon Jun 23, 2017
Ronny Friman (@R00GER) that looks like a separate bug, it should probably have its own issue.
RyanCavanaugh commentedon Aug 15, 2018
Daniel Rosenwasser (@DanielRosenwasser) can you give an update on next steps here?
xialvjun commentedon May 16, 2019
There shouldn't be a type
TemplateStringsArray, it should be aconst string tuple type, so we can write code: