Concrete type is not assignable to generic type











up vote
1
down vote

favorite
1












type Id = <A>(a: A) => A

const id: Id = (a: number) => a;


If I use generics in this way the compiler will return an error saying



Type '(a: number) => number' is not assignable to type 'Id'.
Types of parameters 'a' and 'a' are incompatible.
Type 'A' is not assignable to type 'number'.


I know it can be solved with
type Id<A> = (a: A) => A
But what if I can't declare A at every point. Is there a way to just have it flow through, or be inferred?










share|improve this question


















  • 1




    If you remove the type annotation from the id const it should be assignable to types of Id<number>
    – Michael
    Nov 18 at 21:19










  • @Michael that's correct. But as soon as I want to do something with a the compiler starts complaining: const id: Id = (a) => (a + 1); Operator '+' cannot be applied to types 'A' and '1'.
    – bbz
    Nov 19 at 8:12










  • @Michael is telling you (@bbz) that you should just write const id = (a: number) => (a + 1);. You don't need a type annotation on id at all.
    – jcalz
    Nov 19 at 18:41















up vote
1
down vote

favorite
1












type Id = <A>(a: A) => A

const id: Id = (a: number) => a;


If I use generics in this way the compiler will return an error saying



Type '(a: number) => number' is not assignable to type 'Id'.
Types of parameters 'a' and 'a' are incompatible.
Type 'A' is not assignable to type 'number'.


I know it can be solved with
type Id<A> = (a: A) => A
But what if I can't declare A at every point. Is there a way to just have it flow through, or be inferred?










share|improve this question


















  • 1




    If you remove the type annotation from the id const it should be assignable to types of Id<number>
    – Michael
    Nov 18 at 21:19










  • @Michael that's correct. But as soon as I want to do something with a the compiler starts complaining: const id: Id = (a) => (a + 1); Operator '+' cannot be applied to types 'A' and '1'.
    – bbz
    Nov 19 at 8:12










  • @Michael is telling you (@bbz) that you should just write const id = (a: number) => (a + 1);. You don't need a type annotation on id at all.
    – jcalz
    Nov 19 at 18:41













up vote
1
down vote

favorite
1









up vote
1
down vote

favorite
1






1





type Id = <A>(a: A) => A

const id: Id = (a: number) => a;


If I use generics in this way the compiler will return an error saying



Type '(a: number) => number' is not assignable to type 'Id'.
Types of parameters 'a' and 'a' are incompatible.
Type 'A' is not assignable to type 'number'.


I know it can be solved with
type Id<A> = (a: A) => A
But what if I can't declare A at every point. Is there a way to just have it flow through, or be inferred?










share|improve this question













type Id = <A>(a: A) => A

const id: Id = (a: number) => a;


If I use generics in this way the compiler will return an error saying



Type '(a: number) => number' is not assignable to type 'Id'.
Types of parameters 'a' and 'a' are incompatible.
Type 'A' is not assignable to type 'number'.


I know it can be solved with
type Id<A> = (a: A) => A
But what if I can't declare A at every point. Is there a way to just have it flow through, or be inferred?







typescript






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 18 at 19:12









bbz

638




638








  • 1




    If you remove the type annotation from the id const it should be assignable to types of Id<number>
    – Michael
    Nov 18 at 21:19










  • @Michael that's correct. But as soon as I want to do something with a the compiler starts complaining: const id: Id = (a) => (a + 1); Operator '+' cannot be applied to types 'A' and '1'.
    – bbz
    Nov 19 at 8:12










  • @Michael is telling you (@bbz) that you should just write const id = (a: number) => (a + 1);. You don't need a type annotation on id at all.
    – jcalz
    Nov 19 at 18:41














  • 1




    If you remove the type annotation from the id const it should be assignable to types of Id<number>
    – Michael
    Nov 18 at 21:19










  • @Michael that's correct. But as soon as I want to do something with a the compiler starts complaining: const id: Id = (a) => (a + 1); Operator '+' cannot be applied to types 'A' and '1'.
    – bbz
    Nov 19 at 8:12










  • @Michael is telling you (@bbz) that you should just write const id = (a: number) => (a + 1);. You don't need a type annotation on id at all.
    – jcalz
    Nov 19 at 18:41








1




1




If you remove the type annotation from the id const it should be assignable to types of Id<number>
– Michael
Nov 18 at 21:19




If you remove the type annotation from the id const it should be assignable to types of Id<number>
– Michael
Nov 18 at 21:19












@Michael that's correct. But as soon as I want to do something with a the compiler starts complaining: const id: Id = (a) => (a + 1); Operator '+' cannot be applied to types 'A' and '1'.
– bbz
Nov 19 at 8:12




@Michael that's correct. But as soon as I want to do something with a the compiler starts complaining: const id: Id = (a) => (a + 1); Operator '+' cannot be applied to types 'A' and '1'.
– bbz
Nov 19 at 8:12












@Michael is telling you (@bbz) that you should just write const id = (a: number) => (a + 1);. You don't need a type annotation on id at all.
– jcalz
Nov 19 at 18:41




@Michael is telling you (@bbz) that you should just write const id = (a: number) => (a + 1);. You don't need a type annotation on id at all.
– jcalz
Nov 19 at 18:41












1 Answer
1






active

oldest

votes

















up vote
1
down vote













I think what you're experiencing is the difference between these two type definitions.



type Func1<A> = (a: A) =>  A;

type Func2 = <A>(a: A) => A;


Any function of type Func1<A> must specify its type at the time it is defined.



const func1: Func1<number> = (a: number): number => a;

func1(10); // works
func1("x"); // fails - we already decided it is of type `number`


Anything of type Func2 must not specify its type until it is called.



const func2: Func2 = <X>(a: X): X => a;

func2(10); // works
func2("x"); // works


Here is a playground link that illustrates.



The problem you were experiencing happened because you tried to specify the type of the function when you defined it instead of when you called it.






share|improve this answer























  • Thanks Shaun. Like I mentioned I'm aware of the difference. But your answer makes it a lot more clear!
    – bbz
    Nov 19 at 8:20











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53364524%2fconcrete-type-is-not-assignable-to-generic-type%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
1
down vote













I think what you're experiencing is the difference between these two type definitions.



type Func1<A> = (a: A) =>  A;

type Func2 = <A>(a: A) => A;


Any function of type Func1<A> must specify its type at the time it is defined.



const func1: Func1<number> = (a: number): number => a;

func1(10); // works
func1("x"); // fails - we already decided it is of type `number`


Anything of type Func2 must not specify its type until it is called.



const func2: Func2 = <X>(a: X): X => a;

func2(10); // works
func2("x"); // works


Here is a playground link that illustrates.



The problem you were experiencing happened because you tried to specify the type of the function when you defined it instead of when you called it.






share|improve this answer























  • Thanks Shaun. Like I mentioned I'm aware of the difference. But your answer makes it a lot more clear!
    – bbz
    Nov 19 at 8:20















up vote
1
down vote













I think what you're experiencing is the difference between these two type definitions.



type Func1<A> = (a: A) =>  A;

type Func2 = <A>(a: A) => A;


Any function of type Func1<A> must specify its type at the time it is defined.



const func1: Func1<number> = (a: number): number => a;

func1(10); // works
func1("x"); // fails - we already decided it is of type `number`


Anything of type Func2 must not specify its type until it is called.



const func2: Func2 = <X>(a: X): X => a;

func2(10); // works
func2("x"); // works


Here is a playground link that illustrates.



The problem you were experiencing happened because you tried to specify the type of the function when you defined it instead of when you called it.






share|improve this answer























  • Thanks Shaun. Like I mentioned I'm aware of the difference. But your answer makes it a lot more clear!
    – bbz
    Nov 19 at 8:20













up vote
1
down vote










up vote
1
down vote









I think what you're experiencing is the difference between these two type definitions.



type Func1<A> = (a: A) =>  A;

type Func2 = <A>(a: A) => A;


Any function of type Func1<A> must specify its type at the time it is defined.



const func1: Func1<number> = (a: number): number => a;

func1(10); // works
func1("x"); // fails - we already decided it is of type `number`


Anything of type Func2 must not specify its type until it is called.



const func2: Func2 = <X>(a: X): X => a;

func2(10); // works
func2("x"); // works


Here is a playground link that illustrates.



The problem you were experiencing happened because you tried to specify the type of the function when you defined it instead of when you called it.






share|improve this answer














I think what you're experiencing is the difference between these two type definitions.



type Func1<A> = (a: A) =>  A;

type Func2 = <A>(a: A) => A;


Any function of type Func1<A> must specify its type at the time it is defined.



const func1: Func1<number> = (a: number): number => a;

func1(10); // works
func1("x"); // fails - we already decided it is of type `number`


Anything of type Func2 must not specify its type until it is called.



const func2: Func2 = <X>(a: X): X => a;

func2(10); // works
func2("x"); // works


Here is a playground link that illustrates.



The problem you were experiencing happened because you tried to specify the type of the function when you defined it instead of when you called it.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 19 at 1:08

























answered Nov 19 at 0:50









Shaun Luttin

55.9k32215276




55.9k32215276












  • Thanks Shaun. Like I mentioned I'm aware of the difference. But your answer makes it a lot more clear!
    – bbz
    Nov 19 at 8:20


















  • Thanks Shaun. Like I mentioned I'm aware of the difference. But your answer makes it a lot more clear!
    – bbz
    Nov 19 at 8:20
















Thanks Shaun. Like I mentioned I'm aware of the difference. But your answer makes it a lot more clear!
– bbz
Nov 19 at 8:20




Thanks Shaun. Like I mentioned I'm aware of the difference. But your answer makes it a lot more clear!
– bbz
Nov 19 at 8:20


















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53364524%2fconcrete-type-is-not-assignable-to-generic-type%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Create new schema in PostgreSQL using DBeaver

Deepest pit of an array with Javascript: test on Codility

Costa Masnaga