Skip to content
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

(fix) infer slot/event type from literal string type props #1121

Merged
merged 1 commit into from
Jul 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1223,7 +1223,7 @@ describe('DiagnosticsProvider', () => {
{
code: 2322,
message:
'Type \'"asd"\' is not assignable to type \'number | unique symbol | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | "split" | "substring" | ... 34 more ... | "replaceAll"\'.',
'Type \'"asd"\' is not assignable to type \'number | unique symbol | "anchor" | "toString" | "charAt" | "charCodeAt" | "concat" | "indexOf" | "lastIndexOf" | "localeCompare" | "match" | "replace" | "search" | "slice" | ... 35 more ... | "replaceAll"\'.',
range: {
start: {
character: 25,
Expand Down Expand Up @@ -1290,6 +1290,24 @@ describe('DiagnosticsProvider', () => {
severity: 1,
source: 'ts',
tags: []
},
{
code: 2367,
message:
"This condition will always return 'false' since the types '\"anchor\"' and '\"big\"' have no overlap.",
range: {
end: {
character: 16,
line: 15
},
start: {
character: 5,
line: 15
}
},
tags: [],
severity: 1,
source: 'ts'
}
]);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@
</script>

<!-- valid -->
<Generics a={['a', 'b']} b={'anchor'} c={false} on:b={(e) => e.detail === 'str'} let:a>
{a === 'str'}
<Generics a={['a', 'b']} b={'anchor'} c={false} on:b={(e) => e.detail === 'str'} let:a let:b>
{a === 'str'}{b === 'anchor'}
</Generics>

<!-- invalid -->
<Generics a={['a', 'b']} b={'asd'} c={''} on:b={(e) => e.detail === true} let:a>
{a === true}
</Generics>

<Generics a={['a', 'b']} b={'anchor'} c={false} let:b>
{b === 'big'}
</Generics>
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@
dispatch('b', a[0]);
</script>

<slot a={a[0]} />
<slot a={a[0]} {b} />
27 changes: 19 additions & 8 deletions packages/svelte2tsx/src/htmlxtojsx/utils/node-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,7 @@ function getNameValuePairsFromAttributes(
return { name, value: name, identifier: name };
}
if (val.type === 'Text') {
// Value not important, just that it's typeof text
return { name, value: '""' };
return { name, value: `'${val.data || val.raw}'` };
}
if (val.type === 'MustacheTag') {
const valueStr = originalStr.substring(val.start + 1, val.end - 1);
Expand All @@ -130,18 +129,30 @@ function getNameValuePairsFromAttributes(
}
if (val.expression.type === 'Literal') {
const value =
typeof val.expression.value === 'string' ? '""' : val.expression.value;
typeof val.expression.value === 'string'
? val.expression.raw
: val.expression.value;
return { name, value };
}
return { name, value: valueStr, complexExpression: true };
}
}

// In the case of zero values, the user did attr="", which is the empty string.
// In the case of multiple values, the user did put in a property value
// like a="a{b}c" which is a template literal string. Since we only care
// about the type of the expression in the end, we can simplify this
return { name, value: '""' };
if (!attr.value.length) {
return { name, value: '""' };
}

const value = attr.value
.map((val) =>
val.type === 'Text'
? val.raw
: val.type === 'MustacheTag'
? '$' + originalStr.substring(val.start, val.end)
: ''
)
.join('');

return { name, value: `\`${value}\`` };
});
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<><Parent bare shorthand={shorthand} text1="val1" text2="val2" text3={`a${a}b${b}`} textEmpty="" literal={true} strLiteral={'foo'} complex={{a}} a-dashed-complex={{a}} {...__sveltets_1_cssProp({"--custom-cssprop": `foo`})} >{() => {/*Ωignore_startΩ*/const Ψcomplex={a},Ψa_dashed_complex={a};/*Ωignore_endΩ*/() => { let {foo} = /*Ωignore_startΩ*/new Parent({target: __sveltets_1_any(''), props: {'bare':true, 'shorthand':shorthand, 'text1':"", 'text2':"", 'text3':"", 'textEmpty':"", 'literal':true, 'strLiteral':"", 'complex':Ψcomplex, 'a-dashed-complex':Ψa_dashed_complex}})/*Ωignore_endΩ*/.$$slot_def['default'];<>
{() => { let {bar} = /*Ωignore_startΩ*/new Parent({target: __sveltets_1_any(''), props: {'bare':true, 'shorthand':shorthand, 'text1':"", 'text2':"", 'text3':"", 'textEmpty':"", 'literal':true, 'strLiteral':"", 'complex':Ψcomplex, 'a-dashed-complex':Ψa_dashed_complex}})/*Ωignore_endΩ*/.$$slot_def['named'];<><Component >
<><Parent bare shorthand={shorthand} text1="val1" text2="val2" text3={`a${a}b${b}`} textEmpty="" literal={true} strLiteral={'foo'} complex={{a}} a-dashed-complex={{a}} {...__sveltets_1_cssProp({"--custom-cssprop": `foo`})} >{() => {/*Ωignore_startΩ*/const Ψcomplex={a},Ψa_dashed_complex={a};/*Ωignore_endΩ*/() => { let {foo} = /*Ωignore_startΩ*/new Parent({target: __sveltets_1_any(''), props: {'bare':true, 'shorthand':shorthand, 'text1':'val1', 'text2':'val2', 'text3':`a${a}b${b}`, 'textEmpty':"", 'literal':true, 'strLiteral':'foo', 'complex':Ψcomplex, 'a-dashed-complex':Ψa_dashed_complex}})/*Ωignore_endΩ*/.$$slot_def['default'];<>
{() => { let {bar} = /*Ωignore_startΩ*/new Parent({target: __sveltets_1_any(''), props: {'bare':true, 'shorthand':shorthand, 'text1':'val1', 'text2':'val2', 'text3':`a${a}b${b}`, 'textEmpty':"", 'literal':true, 'strLiteral':'foo', 'complex':Ψcomplex, 'a-dashed-complex':Ψa_dashed_complex}})/*Ωignore_endΩ*/.$$slot_def['named'];<><Component >
{foo} {bar}
</Component></>}}
<div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@



>{() => {/*Ωignore_startΩ*/const Ψsubthing=subthing,Ψshadowed1=shadowed1,Ψshadowed_2=shadowed2,Ψcomplex={complex};/*Ωignore_endΩ*/() => { let {name:n, shadowed1, shadowed2, subthing} = /*Ωignore_startΩ*/new Component({target: __sveltets_1_any(''), props: {'unshadowed1':unshadowed1, 'foo':unshadowed2, 'subthing':Ψsubthing, 'shadowed1':Ψshadowed1, 'shadowed-2':Ψshadowed_2, 'templateString':"", 'complex':Ψcomplex}})/*Ωignore_endΩ*/.$$slot_def['default'];<>
{() => { let {subthing} = /*Ωignore_startΩ*/new Component({target: __sveltets_1_any(''), props: {'unshadowed1':unshadowed1, 'foo':unshadowed2, 'subthing':Ψsubthing, 'shadowed1':Ψshadowed1, 'shadowed-2':Ψshadowed_2, 'templateString':"", 'complex':Ψcomplex}})/*Ωignore_endΩ*/.$$slot_def['sub1'];<><p >{thing}{subthing}</p></>}}
>{() => {/*Ωignore_startΩ*/const Ψsubthing=subthing,Ψshadowed1=shadowed1,Ψshadowed_2=shadowed2,Ψcomplex={complex};/*Ωignore_endΩ*/() => { let {name:n, shadowed1, shadowed2, subthing} = /*Ωignore_startΩ*/new Component({target: __sveltets_1_any(''), props: {'unshadowed1':unshadowed1, 'foo':unshadowed2, 'subthing':Ψsubthing, 'shadowed1':Ψshadowed1, 'shadowed-2':Ψshadowed_2, 'templateString':` ${complex} `, 'complex':Ψcomplex}})/*Ωignore_endΩ*/.$$slot_def['default'];<>
{() => { let {subthing} = /*Ωignore_startΩ*/new Component({target: __sveltets_1_any(''), props: {'unshadowed1':unshadowed1, 'foo':unshadowed2, 'subthing':Ψsubthing, 'shadowed1':Ψshadowed1, 'shadowed-2':Ψshadowed_2, 'templateString':` ${complex} `, 'complex':Ψcomplex}})/*Ωignore_endΩ*/.$$slot_def['sub1'];<><p >{thing}{subthing}</p></>}}

{() => { let {subthing, othersubthing} = /*Ωignore_startΩ*/new Component({target: __sveltets_1_any(''), props: {'unshadowed1':unshadowed1, 'foo':unshadowed2, 'subthing':Ψsubthing, 'shadowed1':Ψshadowed1, 'shadowed-2':Ψshadowed_2, 'templateString':"", 'complex':Ψcomplex}})/*Ωignore_endΩ*/.$$slot_def['sub2'];<><Sub subthing={subthing} >{thing}{subthing}</Sub></>}}
{() => { let {subthing, othersubthing} = /*Ωignore_startΩ*/new Component({target: __sveltets_1_any(''), props: {'unshadowed1':unshadowed1, 'foo':unshadowed2, 'subthing':Ψsubthing, 'shadowed1':Ψshadowed1, 'shadowed-2':Ψshadowed_2, 'templateString':` ${complex} `, 'complex':Ψcomplex}})/*Ωignore_endΩ*/.$$slot_def['sub2'];<><Sub subthing={subthing} >{thing}{subthing}</Sub></>}}

<Sub subthing={subthing} >{() => {/*Ωignore_startΩ*/const Ψsubthing=subthing;/*Ωignore_endΩ*/() => { let {subthing, othersubthing} = /*Ωignore_startΩ*/new Sub({target: __sveltets_1_any(''), props: {'subthing':Ψsubthing}})/*Ωignore_endΩ*/.$$slot_def['default'];<>{thing}{subthing}</>}}}</Sub>
</>}}}</Component></>
Original file line number Diff line number Diff line change
@@ -1 +1 @@
<><Component bare shorthand={shorthand} text1="val1" text2="val2" text3={`a${a}b${b}`} textEmpty="" literal={true} strLiteral={'foo'} complex={{a}} a-dashed-complex={{a}} {...__sveltets_1_cssProp({"--custom-cssprop": `foo`})} />{/*Ωignore_startΩ*/new Component({target: __sveltets_1_any(''), props: {'bare':true, 'shorthand':shorthand, 'text1':"", 'text2':"", 'text3':"", 'textEmpty':"", 'literal':true, 'strLiteral':"", 'complex':{a}, 'a-dashed-complex':{a}}})/*Ωignore_endΩ*/.$on('click', e => e)}</>
<><Component bare shorthand={shorthand} text1="val1" text2="val2" text3={`a${a}b${b}`} textEmpty="" literal={true} strLiteral={'foo'} complex={{a}} a-dashed-complex={{a}} {...__sveltets_1_cssProp({"--custom-cssprop": `foo`})} />{/*Ωignore_startΩ*/new Component({target: __sveltets_1_any(''), props: {'bare':true, 'shorthand':shorthand, 'text1':'val1', 'text2':'val2', 'text3':`a${a}b${b}`, 'textEmpty':"", 'literal':true, 'strLiteral':'foo', 'complex':{a}, 'a-dashed-complex':{a}}})/*Ωignore_endΩ*/.$on('click', e => e)}</>
Original file line number Diff line number Diff line change
Expand Up @@ -429,17 +429,17 @@ s
injectedJS={mapbox_setup}
relaxed {/**
------------------------------------------------------------------------------------------------------------------------------------------------------ */}
/>{/*Ωignore_startΩ*/new Repl({target: __sveltets_1_any(''), props: {'workersUrl':"", 'svelteUrl':svelteUrl, 'rollupUrl':rollupUrl, 'orientation':mobile ? 'columns' : 'rows', 'fixed':mobile, 'injectedJS':mapbox_setup, 'relaxed':true}})/*Ωignore_endΩ*/.$on('change', handle_change)}{/**
╚╚╚/>{/*Ωignore_startΩ*/new•Repl({target:•__sveltets_1_any(''),•props:•{'workersUrl':"",•'svelteUrl':svelteUrl,•'rollupUrl':rollupUrl,•'orientation':mobile•?•'columns'•:•'rows',•'fixed':mobile,•'injectedJS':mapbox_setup,•'relaxed':true}})/*Ωignore_endΩ*/.$on('change',•handle_change)}↲ [generated] line 172
on('change',•handle_change)} [generated] subset
on: change= handle_change}
on:change= handle_change}
╚╚╚╚on:change={handle_change}↲ [original] line 309 (rest generated at line 169)

╚╚╚/>{/*Ωignore_startΩ*/new•Repl({target:•__sveltets_1_any(''),•props:•{'workersUrl':"",•'svelteUrl':svelteUrl,•'rollupUrl':rollupUrl,•'orientation':mobile•?•'columns'•:•'rows',•'fixed':mobile,•'injectedJS':mapbox_setup,•'relaxed':true}})/*Ωignore_endΩ*/.$on('change',•handle_change)}↲ [generated] line 172
╚╚╚/>{/*Ωignore_startΩ*/new•Repl({target:•__sveltets_1_any(''),•props:•{'workersUrl':"",•'svelteUrl':svelteUrl,•'rollupUrl':rollupUrl,•'orientation':mobile•?•'columns'•:•'rows',•'fixed':mobile,•'injectedJS':mapbox_setup,•'relaxed':true}})/*Ωignore_endΩ*/.$ ↲ [generated] subset
╚╚╚/> ↲
╚╚╚/>↲ [original] line 312
/>{/*Ωignore_startΩ*/new Repl({target: __sveltets_1_any(''), props: {'workersUrl':'workers', 'svelteUrl':svelteUrl, 'rollupUrl':rollupUrl, 'orientation':mobile ? 'columns' : 'rows', 'fixed':mobile, 'injectedJS':mapbox_setup, 'relaxed':true}})/*Ωignore_endΩ*/.$on('change', handle_change)}{/**
╚╚╚/>{/*Ωignore_startΩ*/new•Repl({target:•__sveltets_1_any(''),•props:•{'workersUrl':'workers',•'svelteUrl':svelteUrl,•'rollupUrl':rollupUrl,•'orientation':mobile•?•'columns'•:•'rows',•'fixed':mobile,•'injectedJS':mapbox_setup,•'relaxed':true}})/*Ωignore_endΩ*/.$on('change',•handle_change)}↲ [generated] line 172
on('change',•handle_change)} [generated] subset
on: change= handle_change}
on:change= handle_change}
╚╚╚╚on:change={handle_change}↲ [original] line 309 (rest generated at line 169)
╚╚╚/>{/*Ωignore_startΩ*/new•Repl({target:•__sveltets_1_any(''),•props:•{'workersUrl':'workers',•'svelteUrl':svelteUrl,•'rollupUrl':rollupUrl,•'orientation':mobile•?•'columns'•:•'rows',•'fixed':mobile,•'injectedJS':mapbox_setup,•'relaxed':true}})/*Ωignore_endΩ*/.$on('change',•handle_change)}↲ [generated] line 172
╚╚╚/>{/*Ωignore_startΩ*/new•Repl({target:•__sveltets_1_any(''),•props:•{'workersUrl':'workers',•'svelteUrl':svelteUrl,•'rollupUrl':rollupUrl,•'orientation':mobile•?•'columns'•:•'rows',•'fixed':mobile,•'injectedJS':mapbox_setup,•'relaxed':true}})/*Ωignore_endΩ*/.$ ↲ [generated] subset
╚╚╚/>
╚╚╚/>↲ [original] line 312
------------------------------------------------------------------------------------------------------------------------------------------------------ */}
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
///<reference types="svelte" />
<></>;function render() {
/*Ωignore_startΩ*/;const __sveltets_ensureSlot = __sveltets_1_createEnsureSlot();/*Ωignore_endΩ*/
<><Parent propA propB={propB} propC="val1" propD="val2" propE={`a${a}b${b}`} >{() => { let {foo} = /*Ωignore_startΩ*/new Parent({target: __sveltets_1_any(''), props: {'propA':true, 'propB':propB, 'propC':"", 'propD':"", 'propE':""}})/*Ωignore_endΩ*/.$$slot_def['default'];<>
<><Parent propA propB={propB} propC="val1" propD="val2" propE={`a${a}b${b}`} >{() => { let {foo} = /*Ωignore_startΩ*/new Parent({target: __sveltets_1_any(''), props: {'propA':true, 'propB':propB, 'propC':'val1', 'propD':'val2', 'propE':`a${a}b${b}`}})/*Ωignore_endΩ*/.$$slot_def['default'];<>
<slot foo={__sveltets_ensureSlot("default","foo",foo)} />
</>}}</Parent></>
return { props: {}, slots: {'default': {foo:__sveltets_1_instanceOf(Parent).$$slot_def['default'].foo}}, getters: {}, events: {} }}
Expand Down