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

[RFC436] interface delcared in setup function should be elevated to top scope instead of function scope #1966

Closed
HerringtonDarkholme opened this issue Oct 10, 2022 · 5 comments

Comments

@HerringtonDarkholme
Copy link
Member

Input file:

<script setup lang="ts" generic="T extends Test">
interface Test {
  test: string
}
const props = defineProps<{ 
  msg: T,    // no works
  mmm: Test, // works
}>()
console.log(props.msg.test)
</script>

Compiled virtual file

image

Note the interface should be compiled outside of render function.

@xiaoxiangmoe
Copy link
Collaborator

😅temp solution,use export interface Test {}

@Florent-Bouisset
Copy link

Florent-Bouisset commented Oct 13, 2022

it was answered here: #1964 (comment)

You can define your type in a <script> (not setup), not very comfortable to have 2 scripts tag but it works

<script lang="ts">
interface Test {
  test: string
}
</script>

<script setup lang="ts" generic="T extends Test">
const props = defineProps<{ 
  msg: T,    
  mmm: Test,
}>()
console.log(props.msg.test)
</script>

@johnsoncodehk
Copy link
Member

This is expected behavior, consider following case we cannot move Test outside setup function.

<script setup lang="ts">
let test = 'test';
interface Test {
  test: typeof test
}
</script>

@HerringtonDarkholme
Copy link
Member Author

HerringtonDarkholme commented Oct 18, 2022

So the solution here is using another script tag? It is more verbose than being optimal.

Plus, it is not consistent with SFC's defineProps.

Consider this

<script setup lang="ts">
  import { ref } from 'vue'
  interface Test {
    test: string
  }
  
  const props = defineProps<Test>()
</script>

will compile to this successfully.

image

Playground:
https://sfc.vuejs.org/#eNo9ULtuwzAM/BVCS1qgttDVUAz0Dzp01OI6tKPAekCk08HQv5dS0g4SeDyedMdDfaTU33dUgzI0Z5cYCHlPsE1hPVvFZNVoA4DzKWaGAzIuUGDJ0cNJhKdGBsa8TDPCF5IM1R4ASz0AcXZhrZ1Sr3rmGGQq5ZgIznDBxQX8rMhU+fjyaoPRDzfytwBGn7aJsTkx1/fxOMDTCqUYLah1XUg7w73z8YKbOBe+WTf6X63e1CNG56fU3ygGid3M2ichaYc/+1ZJvIqtujInGrSmZa7LulEf86ql6vMe2HnskXz3neMPYZaHrXrmLar8AhA6eUc=

@johnsoncodehk
Copy link
Member

So the solution here is using another script tag? It is more verbose than being optimal.

Yes, I mean elevate interface to top scope is not improvement, but it's a bug.

This is an example, when interface in <script setup> Props.foo is string, when interface in <script> Props.foo is number.

<script lang="ts">
const foo = 123;
</script>

<script lang="ts" setup>
const foo = 'foo';

interface Props {
  foo: typeof foo; // string
}

defineProps<Props>()
</script>
<script lang="ts">
const foo = 123;

interface Props {
  foo: typeof foo; // number
}
</script>

<script lang="ts" setup>
const foo = 'foo';

defineProps<Props>()
</script>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants