-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incomplete support for tagged template literals: String.raw doesn't work #2616
Comments
So, what is correct type for template strings? |
As the message says, I guess it takes an array? I was able to pass flow-check for this code... const someString = dedent`A long template string...`; ...with this declaration of
(I don't know what to put as the Array parameters though) |
The type of a tagged template function should look like this in general (possibly with a different array type for the value parameter): declare function exampleTemplateFunction(templateParts: string[] & {raw: string[]}, ...values: any[]): any; (I'm not really sure if Flow correctly understands this though.) I think String.raw's declaration ought to look like this: declare function stringRaw(templateParts: string[] & {raw: string[]}, ...values: Array<string|number>): string; but I think Flow might still report an error when |
Any updates on this? Plain
fails in the online playground. |
+1 Yeah would be nice to support this. You can essentially get coverage on the fn but then anyone that calls it gets an error or you can get errors in the fn and the calls to it will work kind of. I've been trying various combinations for the below template literal fn const TRAILING_COMMENTS = /\s+#.*$/gm;
const SURROUNDING_WHITESPACE = /^\s+|\s+$/gm;
const LITERAL_NEW_LINES = /[\r\n]/g;
export default function re(flags: string) {
return (strings: { raw: Array<*> } & Array<*>, ...values: Array<?RegExp>) => {
function toPattern(pattern: string, rawString: string, i: number) {
let value = values[i];
if (value == null) {
return pattern + rawString;
}
if (value instanceof RegExp) {
value = value.source;
}
return pattern + rawString + value;
}
const compiledPattern = strings.raw
.reduce(toPattern, '')
.replace(TRAILING_COMMENTS, '')
.replace(SURROUNDING_WHITESPACE, '')
.replace(LITERAL_NEW_LINES, '');
return new RegExp(compiledPattern, flags);
};
}
export const RE_LUA_COMMENTS = re('g')`
(?:
--\[\[(([^\s]+)\s+=>[\S\s]*?)\]\]
)|
(?:
--\s*\|\s*([^\s\n]+):\s+([^\n]+)
)
`; |
+1 |
f8875fd is part of the fix, however https://github.com/facebook/flow/blob/master/lib/core.js#L329-L330 seems wrong. As a standard libdef it should probably be:
However that implies that you could call it as a normal function and supply an array of strings which you cannot do. Maybe flow could add a special case for this function, @mroch ? |
@leebyron I think my post above has the right types, and shouldn't need any special-casing from Flow: #2616 (comment). |
Just ran into this as well. If we're going to be precise about this, looking at the spec, the correct typedef for the first parameter would be something along the lines of |
This isn't error in library definitions @jbrown215 correct me if I'm wrong but first argument of template tag should flow into upper bound of $ReadOnlyArray (aka Lines 3220 to 3226 in aaa8067
So this should work like this declare class TemplateStringsArray extends $ReadOnlyArray<string> {
+raw: string;
}
// error
declare function raw(strings: {|+raw: string|}, ...substitutions: any[]): string;
// error
declare function raw(strings: number, ...substitutions: any[]): string;
// no error
declare function raw(strings: $ReadOnlyArray<string>, ...substitutions: any[]): string;
// no error
declare function raw(strings: TemplateStringsArray, ...substitutions: any[]): string;
// no error
declare function raw(strings: Array<string>, ...substitutions: any[]): string; |
Summary: Tagged template literals produce an array with a read-only `raw` property that contains an array of strings. The current type is simply wrong, and [we didn't correctly type `String.raw` at all](https://flow.org/try/#0MYewdgzgLgBAHjAvDAylATgSzAcwHToCGA7gAYBmIIpA3EA). Notes: - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/raw - https://tc39.es/ecma262/#sec-gettemplateobject - https://tc39.es/ecma262/#sec-string.raw Changelog: [errors] Fix type created by tagged template literals and `String.raw` Closes #7580 Fixes #5705 Fixes #2616 Reviewed By: SamChou19815 Differential Revision: D42731497 (a6fa1c2) ------------------------------------------------------------------------ (from 3af4b54520666520018907478c76470a3adf171a) fbshipit-source-id: 625089fc1e1c3accd6e9c201822d2e45e36bd6d7
It seems like Flow's type definition for String.raw is broken because String.raw appears to always fail:
Here's Flow's type definition for String.raw:
The first overload just seems wrong because String.raw can't be called on plain strings. The second overload isn't perfect (substitutions ought to be
string[]
I think. And what is$Shape
for? Would{raw: string}
not be enough?) but I think it looks like it ought to work. Maybe Flow doesn't treat tagged template strings as having araw
property?The text was updated successfully, but these errors were encountered: