Mapped record causes type any when recursiveTypescript: How to define type for a function callback (as any function type, not universal any) used in a method parameterHow do I prevent the error “Index signature of object type implicitly has an 'any' type” when compiling typescript with noImplicitAny flag enabled?Import class in definition file (*d.ts)Typescript type mapping to expect an object where every property is of a given typeTypeScript: Using Mapped Types with GenericsTypeScript: Conditional Mapped Types and Generic Type ParametersReflect and map typed argument shape in typescript?Enzyme change another input fieldA type-safe way to recursively map a class to its JSON representationHow can I get mapped type names for a graphQL type using type-graphql
A steel cutting sword?
What was the idiom for something that we take without a doubt?
Is "cool" appropriate or offensive to use in IMs?
Pirate democracy at its finest
Could a 19.25mm revolver actually exist?
What are the mechanical differences between the uncommon Medallion of Thoughts and the rare Potion of Mind Reading?
NIntegrate doesn't evaluate
Why didn't Project Mercury advance to an orbital flight on their second mission?
Sitecore 9.0 works with solr 7.2.1?
Find the names of these countries
Have 1.5% of all nuclear reactors ever built melted down?
What are the real benefits of using Salesforce DX?
Why does this if-statement combining assignment and an equality check return true?
Caught student / friend cheating on the final exam that I proctored
What is Theresa May waiting for?
The usage of "run a mile" in a sentence
Make 24 using exactly three 3s
Teacher help me explain this to my students
Installed Tankless Water Heater - Internet loss when active
The art of clickbait captions
How to know if a folder is a symbolic link?
How to patch glass cuts in a bicycle tire?
Why aren't space telescopes put in GEO?
How do I partition a matrx into blocks and replace zeros with dots?
Mapped record causes type any when recursive
Typescript: How to define type for a function callback (as any function type, not universal any) used in a method parameterHow do I prevent the error “Index signature of object type implicitly has an 'any' type” when compiling typescript with noImplicitAny flag enabled?Import class in definition file (*d.ts)Typescript type mapping to expect an object where every property is of a given typeTypeScript: Using Mapped Types with GenericsTypeScript: Conditional Mapped Types and Generic Type ParametersReflect and map typed argument shape in typescript?Enzyme change another input fieldA type-safe way to recursively map a class to its JSON representationHow can I get mapped type names for a graphQL type using type-graphql
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
I'm using mapped types to transform a data structure, which works as expected except when there is a recursive field.
Is there a way to prevent it from becoming type any?
type DataType<T extends Record<keyof T, Obj<any, any>>> =
[P in keyof T]: T[P]['data']
// I need to be able to pass in a Data generic
// to this object
class Obj<
Data extends DataType<T>,
T extends Record<keyof Data, Obj<any, any>>
>
constructor(public fields: T)
public data: Data
const recursive = new Obj(
// With this field, the 'recursive' variable becomes type 'any'
get query()
return recursive
,
test: new Obj()
)
// Without recursive field it works as expected
const nonRecursive = new Obj( test: new Obj() )
nonRecursive.data.test // okay
typescript
add a comment |
I'm using mapped types to transform a data structure, which works as expected except when there is a recursive field.
Is there a way to prevent it from becoming type any?
type DataType<T extends Record<keyof T, Obj<any, any>>> =
[P in keyof T]: T[P]['data']
// I need to be able to pass in a Data generic
// to this object
class Obj<
Data extends DataType<T>,
T extends Record<keyof Data, Obj<any, any>>
>
constructor(public fields: T)
public data: Data
const recursive = new Obj(
// With this field, the 'recursive' variable becomes type 'any'
get query()
return recursive
,
test: new Obj()
)
// Without recursive field it works as expected
const nonRecursive = new Obj( test: new Obj() )
nonRecursive.data.test // okay
typescript
add a comment |
I'm using mapped types to transform a data structure, which works as expected except when there is a recursive field.
Is there a way to prevent it from becoming type any?
type DataType<T extends Record<keyof T, Obj<any, any>>> =
[P in keyof T]: T[P]['data']
// I need to be able to pass in a Data generic
// to this object
class Obj<
Data extends DataType<T>,
T extends Record<keyof Data, Obj<any, any>>
>
constructor(public fields: T)
public data: Data
const recursive = new Obj(
// With this field, the 'recursive' variable becomes type 'any'
get query()
return recursive
,
test: new Obj()
)
// Without recursive field it works as expected
const nonRecursive = new Obj( test: new Obj() )
nonRecursive.data.test // okay
typescript
I'm using mapped types to transform a data structure, which works as expected except when there is a recursive field.
Is there a way to prevent it from becoming type any?
type DataType<T extends Record<keyof T, Obj<any, any>>> =
[P in keyof T]: T[P]['data']
// I need to be able to pass in a Data generic
// to this object
class Obj<
Data extends DataType<T>,
T extends Record<keyof Data, Obj<any, any>>
>
constructor(public fields: T)
public data: Data
const recursive = new Obj(
// With this field, the 'recursive' variable becomes type 'any'
get query()
return recursive
,
test: new Obj()
)
// Without recursive field it works as expected
const nonRecursive = new Obj( test: new Obj() )
nonRecursive.data.test // okay
typescript
typescript
asked Mar 24 at 3:56
samddsamdd
2,37421326
2,37421326
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Hmm, you're carrying around a lot of mutually referential generic types here, and without a use case and examples I admit I have almost no idea what's going on here and if this is really the best way to represent your data structure. I'd guess you could probably get away with a single type parameter like this:
class Obj<T>
constructor(public fields: [K in keyof T]: Obj<T[K]> )
public data!: T
But even if you do that you will still have the same issue, which gets exposed if you enable the stricter compiler options like --noImplicitAny
or --strict
. Then you will see that your definition of recursive
gives you the following errors:
'recursive' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
and
'query' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
This is the intended behavior when the compiler cannot infer a type because it depends on itself in certain ways. The suggested way to deal with this is usually to give an explicit type annotation to one of the pieces to break the circularity. It's annoying because it forces you to redundantly write out typings to things that were previously inferred by the compiler, but I don't know if there's a good way to avoid that.
Here's one way of doing it with the types as you have them:
// explicit type
interface RecursiveObj extends Obj<
DataType<
readonly query: RecursiveObj; test: Obj<, >;
>, readonly query: RecursiveObj; test: Obj<, >; >
const recursive = new Obj(
// explicitly annotated return type
get query(): RecursiveObj
return recursive
,
test: new Obj()
); // okay now
And here's how I'd do it with the simplified Obj<T>
type I listed above:
// explicit type
interface RecursiveData
readonly query: RecursiveData,
test:
const recursive = new Obj(
// explicitly annotated return type
get query(): Obj<RecursiveData>
return recursive
,
test: new Obj()
); // okay now
Okay, hope that helps. Good luck!
add a comment |
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',
autoActivateHeartbeat: false,
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55320592%2fmapped-record-causes-type-any-when-recursive%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
Hmm, you're carrying around a lot of mutually referential generic types here, and without a use case and examples I admit I have almost no idea what's going on here and if this is really the best way to represent your data structure. I'd guess you could probably get away with a single type parameter like this:
class Obj<T>
constructor(public fields: [K in keyof T]: Obj<T[K]> )
public data!: T
But even if you do that you will still have the same issue, which gets exposed if you enable the stricter compiler options like --noImplicitAny
or --strict
. Then you will see that your definition of recursive
gives you the following errors:
'recursive' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
and
'query' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
This is the intended behavior when the compiler cannot infer a type because it depends on itself in certain ways. The suggested way to deal with this is usually to give an explicit type annotation to one of the pieces to break the circularity. It's annoying because it forces you to redundantly write out typings to things that were previously inferred by the compiler, but I don't know if there's a good way to avoid that.
Here's one way of doing it with the types as you have them:
// explicit type
interface RecursiveObj extends Obj<
DataType<
readonly query: RecursiveObj; test: Obj<, >;
>, readonly query: RecursiveObj; test: Obj<, >; >
const recursive = new Obj(
// explicitly annotated return type
get query(): RecursiveObj
return recursive
,
test: new Obj()
); // okay now
And here's how I'd do it with the simplified Obj<T>
type I listed above:
// explicit type
interface RecursiveData
readonly query: RecursiveData,
test:
const recursive = new Obj(
// explicitly annotated return type
get query(): Obj<RecursiveData>
return recursive
,
test: new Obj()
); // okay now
Okay, hope that helps. Good luck!
add a comment |
Hmm, you're carrying around a lot of mutually referential generic types here, and without a use case and examples I admit I have almost no idea what's going on here and if this is really the best way to represent your data structure. I'd guess you could probably get away with a single type parameter like this:
class Obj<T>
constructor(public fields: [K in keyof T]: Obj<T[K]> )
public data!: T
But even if you do that you will still have the same issue, which gets exposed if you enable the stricter compiler options like --noImplicitAny
or --strict
. Then you will see that your definition of recursive
gives you the following errors:
'recursive' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
and
'query' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
This is the intended behavior when the compiler cannot infer a type because it depends on itself in certain ways. The suggested way to deal with this is usually to give an explicit type annotation to one of the pieces to break the circularity. It's annoying because it forces you to redundantly write out typings to things that were previously inferred by the compiler, but I don't know if there's a good way to avoid that.
Here's one way of doing it with the types as you have them:
// explicit type
interface RecursiveObj extends Obj<
DataType<
readonly query: RecursiveObj; test: Obj<, >;
>, readonly query: RecursiveObj; test: Obj<, >; >
const recursive = new Obj(
// explicitly annotated return type
get query(): RecursiveObj
return recursive
,
test: new Obj()
); // okay now
And here's how I'd do it with the simplified Obj<T>
type I listed above:
// explicit type
interface RecursiveData
readonly query: RecursiveData,
test:
const recursive = new Obj(
// explicitly annotated return type
get query(): Obj<RecursiveData>
return recursive
,
test: new Obj()
); // okay now
Okay, hope that helps. Good luck!
add a comment |
Hmm, you're carrying around a lot of mutually referential generic types here, and without a use case and examples I admit I have almost no idea what's going on here and if this is really the best way to represent your data structure. I'd guess you could probably get away with a single type parameter like this:
class Obj<T>
constructor(public fields: [K in keyof T]: Obj<T[K]> )
public data!: T
But even if you do that you will still have the same issue, which gets exposed if you enable the stricter compiler options like --noImplicitAny
or --strict
. Then you will see that your definition of recursive
gives you the following errors:
'recursive' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
and
'query' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
This is the intended behavior when the compiler cannot infer a type because it depends on itself in certain ways. The suggested way to deal with this is usually to give an explicit type annotation to one of the pieces to break the circularity. It's annoying because it forces you to redundantly write out typings to things that were previously inferred by the compiler, but I don't know if there's a good way to avoid that.
Here's one way of doing it with the types as you have them:
// explicit type
interface RecursiveObj extends Obj<
DataType<
readonly query: RecursiveObj; test: Obj<, >;
>, readonly query: RecursiveObj; test: Obj<, >; >
const recursive = new Obj(
// explicitly annotated return type
get query(): RecursiveObj
return recursive
,
test: new Obj()
); // okay now
And here's how I'd do it with the simplified Obj<T>
type I listed above:
// explicit type
interface RecursiveData
readonly query: RecursiveData,
test:
const recursive = new Obj(
// explicitly annotated return type
get query(): Obj<RecursiveData>
return recursive
,
test: new Obj()
); // okay now
Okay, hope that helps. Good luck!
Hmm, you're carrying around a lot of mutually referential generic types here, and without a use case and examples I admit I have almost no idea what's going on here and if this is really the best way to represent your data structure. I'd guess you could probably get away with a single type parameter like this:
class Obj<T>
constructor(public fields: [K in keyof T]: Obj<T[K]> )
public data!: T
But even if you do that you will still have the same issue, which gets exposed if you enable the stricter compiler options like --noImplicitAny
or --strict
. Then you will see that your definition of recursive
gives you the following errors:
'recursive' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.
and
'query' implicitly has return type 'any' because it does not have a return type annotation and is referenced directly or indirectly in one of its return expressions.
This is the intended behavior when the compiler cannot infer a type because it depends on itself in certain ways. The suggested way to deal with this is usually to give an explicit type annotation to one of the pieces to break the circularity. It's annoying because it forces you to redundantly write out typings to things that were previously inferred by the compiler, but I don't know if there's a good way to avoid that.
Here's one way of doing it with the types as you have them:
// explicit type
interface RecursiveObj extends Obj<
DataType<
readonly query: RecursiveObj; test: Obj<, >;
>, readonly query: RecursiveObj; test: Obj<, >; >
const recursive = new Obj(
// explicitly annotated return type
get query(): RecursiveObj
return recursive
,
test: new Obj()
); // okay now
And here's how I'd do it with the simplified Obj<T>
type I listed above:
// explicit type
interface RecursiveData
readonly query: RecursiveData,
test:
const recursive = new Obj(
// explicitly annotated return type
get query(): Obj<RecursiveData>
return recursive
,
test: new Obj()
); // okay now
Okay, hope that helps. Good luck!
answered Mar 25 at 1:08
jcalzjcalz
36k23253
36k23253
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f55320592%2fmapped-record-causes-type-any-when-recursive%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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