Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.5k views
in Technique[技术] by (71.8m points)

typescript - how can you express "keyof T" to be a subset of String?

The Firebase typings have an interface IQuery which has the equalTo() method typed as:

public equalTo(value: number | string | boolean | null, name?: string): IQuery;

I have a mocking library which is trying to mimic the API surface of what Firebase is exposing but in the case of the name parameter the general typing of "string" can be made more specific:

 public equalTo(value: number | string | boolean | null, key?: keyof T): IQuery<T>

By stating keyof T we get some very useful static checking that I'd hate to lose out on and in fact up to TypeScript 2.8.3 I seemed to be able to do this but when moving to 2.9.x+ of Typescript I now get this error:

Type 'string' is not assignable to type 'keyof T'.

For a bit more context, the class definition in my mocking library is:

 export default class Query<T = any> implements IQuery<T> { ... }

Where the <T> generic type is an indicator of type of the data structure that the query will return.

Further it is worth noting that T, will always be shaped as a dictionary/hash with string keys and therefore keyof T will subset of string values but in my typing I'm not making this clear so I get where Typescript is taking issue ... I just don't know how to express that keyof T must be a string.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This is related to a change in the way keyof works in 2.9, until 2.9 keyof only returned string keys, from 2.9 onward it will return number and symbol keys. This is the reference for this

To only accept string keys you can use Extract<keyof T, string> as the type for the key parameter, or if you want to revert to the old behavior you can use the --keyofStringsOnly compiler flag

public equalTo(value: number | string | boolean | null, key?: Extract<keyof T, string>): IQuery<T>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...