admin管理员组文章数量:1022989
I am writing a library to define schemas.
Consider the following example:
type Cardinality = 'many' | 'one';
type ValueType = 'string' | 'number';
interface ILinkDef<Source> {
fwdCardinality: Cardinality;
revNamespace: keyof Source;
revCardinality: Cardinality;
revLabel: string;
}
interface IAttrsDef {
[label: string]: ValueType
}
interface ILinksDef<Source> {
[label: string]: ILinkDef<Source>
}
interface ISchemaDef<Source> {
[table: string]: {
attrs: IAttrsDef;
links: ILinksDef<Source>;
};
}
class Schema<D extends ISchemaDef<any>> {
defs: D
constructor(
defs: D,
) {
this.defs = defs
}
}
function schema<D extends ISchemaDef<D>>(defs: D) {
return new Schema<D>(defs);
}
const s = schema({
posts: {
attrs: {
title: 'string'
},
links: {
owner: {
fwdCardinality: 'one',
revNamespace: 'users',
revLabel: 'ownedPosts',
revCardinality: 'many'
}
}
},
users: {
attrs: {
email: 'string'
},
links: {}
}
})
type OwnerLink = typeof s.defs.posts.links.owner
Problem
OwnerLink
returns the following inference:
type OwnerLink = {
fwdCardinality: "one";
revNamespace: "users";
revLabel: string;
revCardinality: "many";
}
I am really happy to have the literal values for fwdCardinality
, revCardinality
, etc.
However, I can't get revLabel
to refine itself into it's literal value. I would love for revLabel
to be 'ownedPosts'
Question
How could I get revLabel
to keep the inference to it's literal argument, when possible?
Playground Link
I am writing a library to define schemas.
Consider the following example:
type Cardinality = 'many' | 'one';
type ValueType = 'string' | 'number';
interface ILinkDef<Source> {
fwdCardinality: Cardinality;
revNamespace: keyof Source;
revCardinality: Cardinality;
revLabel: string;
}
interface IAttrsDef {
[label: string]: ValueType
}
interface ILinksDef<Source> {
[label: string]: ILinkDef<Source>
}
interface ISchemaDef<Source> {
[table: string]: {
attrs: IAttrsDef;
links: ILinksDef<Source>;
};
}
class Schema<D extends ISchemaDef<any>> {
defs: D
constructor(
defs: D,
) {
this.defs = defs
}
}
function schema<D extends ISchemaDef<D>>(defs: D) {
return new Schema<D>(defs);
}
const s = schema({
posts: {
attrs: {
title: 'string'
},
links: {
owner: {
fwdCardinality: 'one',
revNamespace: 'users',
revLabel: 'ownedPosts',
revCardinality: 'many'
}
}
},
users: {
attrs: {
email: 'string'
},
links: {}
}
})
type OwnerLink = typeof s.defs.posts.links.owner
Problem
OwnerLink
returns the following inference:
type OwnerLink = {
fwdCardinality: "one";
revNamespace: "users";
revLabel: string;
revCardinality: "many";
}
I am really happy to have the literal values for fwdCardinality
, revCardinality
, etc.
However, I can't get revLabel
to refine itself into it's literal value. I would love for revLabel
to be 'ownedPosts'
Question
How could I get revLabel
to keep the inference to it's literal argument, when possible?
Playground Link
Share Improve this question asked Nov 19, 2024 at 1:52 Stepan ParunashviliStepan Parunashvili 2,8456 gold badges35 silver badges57 bronze badges 2 |1 Answer
Reset to default 1Your original definition of ILinkDef
specifies revLabel
to be just string
. It can be changed to a generic, though. For example:
type Cardinality = 'many' | 'one';
type ValueType = 'string' | 'number';
interface ILinkDef<Source, T extends string = string> {
fwdCardinality: Cardinality;
revNamespace: keyof Source;
revCardinality: Cardinality;
revLabel: T;
}
interface IAttrsDef {
[label: string]: ValueType
}
interface ILinksDef<Source, T extends string = string> {
[label: string]: ILinkDef<Source, T>
}
interface ISchemaDef<Source, T extends string = string> {
[table: string]: {
attrs: IAttrsDef;
links: ILinksDef<Source, T>;
};
}
class Schema<D extends ISchemaDef<any, any>> {
defs: D
constructor(
defs: D,
) {
this.defs = defs
}
}
function schema<D extends ISchemaDef<D, T>, T extends string = string>(defs: D) {
return new Schema<D>(defs);
}
const s = schema({
posts: {
attrs: {
title: 'string'
},
links: {
owner: {
fwdCardinality: 'one',
revNamespace: 'users',
revLabel: 'ownedPosts',
revCardinality: 'many'
}
}
},
users: {
attrs: {
email: 'string'
},
links: {}
}
})
type OwnerLink = typeof s.defs.posts.links.owner
Playground Link
I am writing a library to define schemas.
Consider the following example:
type Cardinality = 'many' | 'one';
type ValueType = 'string' | 'number';
interface ILinkDef<Source> {
fwdCardinality: Cardinality;
revNamespace: keyof Source;
revCardinality: Cardinality;
revLabel: string;
}
interface IAttrsDef {
[label: string]: ValueType
}
interface ILinksDef<Source> {
[label: string]: ILinkDef<Source>
}
interface ISchemaDef<Source> {
[table: string]: {
attrs: IAttrsDef;
links: ILinksDef<Source>;
};
}
class Schema<D extends ISchemaDef<any>> {
defs: D
constructor(
defs: D,
) {
this.defs = defs
}
}
function schema<D extends ISchemaDef<D>>(defs: D) {
return new Schema<D>(defs);
}
const s = schema({
posts: {
attrs: {
title: 'string'
},
links: {
owner: {
fwdCardinality: 'one',
revNamespace: 'users',
revLabel: 'ownedPosts',
revCardinality: 'many'
}
}
},
users: {
attrs: {
email: 'string'
},
links: {}
}
})
type OwnerLink = typeof s.defs.posts.links.owner
Problem
OwnerLink
returns the following inference:
type OwnerLink = {
fwdCardinality: "one";
revNamespace: "users";
revLabel: string;
revCardinality: "many";
}
I am really happy to have the literal values for fwdCardinality
, revCardinality
, etc.
However, I can't get revLabel
to refine itself into it's literal value. I would love for revLabel
to be 'ownedPosts'
Question
How could I get revLabel
to keep the inference to it's literal argument, when possible?
Playground Link
I am writing a library to define schemas.
Consider the following example:
type Cardinality = 'many' | 'one';
type ValueType = 'string' | 'number';
interface ILinkDef<Source> {
fwdCardinality: Cardinality;
revNamespace: keyof Source;
revCardinality: Cardinality;
revLabel: string;
}
interface IAttrsDef {
[label: string]: ValueType
}
interface ILinksDef<Source> {
[label: string]: ILinkDef<Source>
}
interface ISchemaDef<Source> {
[table: string]: {
attrs: IAttrsDef;
links: ILinksDef<Source>;
};
}
class Schema<D extends ISchemaDef<any>> {
defs: D
constructor(
defs: D,
) {
this.defs = defs
}
}
function schema<D extends ISchemaDef<D>>(defs: D) {
return new Schema<D>(defs);
}
const s = schema({
posts: {
attrs: {
title: 'string'
},
links: {
owner: {
fwdCardinality: 'one',
revNamespace: 'users',
revLabel: 'ownedPosts',
revCardinality: 'many'
}
}
},
users: {
attrs: {
email: 'string'
},
links: {}
}
})
type OwnerLink = typeof s.defs.posts.links.owner
Problem
OwnerLink
returns the following inference:
type OwnerLink = {
fwdCardinality: "one";
revNamespace: "users";
revLabel: string;
revCardinality: "many";
}
I am really happy to have the literal values for fwdCardinality
, revCardinality
, etc.
However, I can't get revLabel
to refine itself into it's literal value. I would love for revLabel
to be 'ownedPosts'
Question
How could I get revLabel
to keep the inference to it's literal argument, when possible?
Playground Link
Share Improve this question asked Nov 19, 2024 at 1:52 Stepan ParunashviliStepan Parunashvili 2,8456 gold badges35 silver badges57 bronze badges 2-
the definition of
ILinkDef
specifiesrevLabel
to be juststring
, though. Do you want to change it to a generic? – qrsngky Commented Nov 19, 2024 at 1:55 - I would love to change it to be generic, but I am not sure how I would then 'fill' in that generic value with what is provided in the schema – Stepan Parunashvili Commented Nov 19, 2024 at 2:01
1 Answer
Reset to default 1Your original definition of ILinkDef
specifies revLabel
to be just string
. It can be changed to a generic, though. For example:
type Cardinality = 'many' | 'one';
type ValueType = 'string' | 'number';
interface ILinkDef<Source, T extends string = string> {
fwdCardinality: Cardinality;
revNamespace: keyof Source;
revCardinality: Cardinality;
revLabel: T;
}
interface IAttrsDef {
[label: string]: ValueType
}
interface ILinksDef<Source, T extends string = string> {
[label: string]: ILinkDef<Source, T>
}
interface ISchemaDef<Source, T extends string = string> {
[table: string]: {
attrs: IAttrsDef;
links: ILinksDef<Source, T>;
};
}
class Schema<D extends ISchemaDef<any, any>> {
defs: D
constructor(
defs: D,
) {
this.defs = defs
}
}
function schema<D extends ISchemaDef<D, T>, T extends string = string>(defs: D) {
return new Schema<D>(defs);
}
const s = schema({
posts: {
attrs: {
title: 'string'
},
links: {
owner: {
fwdCardinality: 'one',
revNamespace: 'users',
revLabel: 'ownedPosts',
revCardinality: 'many'
}
}
},
users: {
attrs: {
email: 'string'
},
links: {}
}
})
type OwnerLink = typeof s.defs.posts.links.owner
Playground Link
本文标签:
版权声明:本文标题:How to get typescript to infer the literal string value for a type, rather than the generic `string` - Stack Overflow 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://it.en369.cn/questions/1745586358a2157619.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
ILinkDef
specifiesrevLabel
to be juststring
, though. Do you want to change it to a generic? – qrsngky Commented Nov 19, 2024 at 1:55