Branding Drafts on Type level
Mantenedores costumam responder em até 4 dias
Ninguém assumiu esta issue ainda.
Avaliação
- Dificuldade
- 5/5
- Tempo estimado
- Mais de uma semana
- Facilidade para iniciantes
- 35/100
- Tipo de issue
- Funcionalidade
- Clareza
- Precisa de esclarecimento
- Status de atividade
- Pouca atividade
- Stack de tecnologia
- typescript
- Domínio
- developer-experience
Direção de pesquisa
Comece com a prova de conceito do TypeScript Playground e compare o comportamento relacionado a branded Draft, MaybeDraft, current, isDraft e produce com as assinaturas de tipo existentes do Immer. A issue não especifica arquivos nem testes do repositório; para considerá-la concluída, seria necessário chegar a uma decisão acordada sobre se o branding em tempo de compilação é desejável e definir o escopo da implementação.
Escrita pelo modelo de indexação a partir do texto da issue.
Descrição
🙋♂ Question
I was wondering if it would be possible to not just brand at runtime, but branded type at compile time as well?
Cause
I was using redux/toolkit, which uses Immer and had an issue where current(val) was called on a non draft, typechecker was fine, executed it in development, all good, came to production, tried to unwrap a non draft and crashed. Not a big deal, just use isDraft, but it was something technically avoidable if....
Implementation
I could make a PR, I just wanted to figure out if that is even desirable since I assume this question came up already some time ago and was decided against it for a reason to me currently unknown (except maybe that some types are already relatively complex)
Proof of concept
I made a small proof of concept on typescript playground relative quickly to just check out the branding, the idea would be that produce etc return Drafted<T> instead of T hiding a potential source for errors (naming still up for discussion)
I made a small code example on TS playground where I do not duplicate the objects, Proxy them etc for simplicity. If no link should be used, here the snipped:
const brand : unique symbol = Symbol("foobar")
type Draft<T> = T & {[brand]:never}
type MaybeDraft<T> = Draft<T> | T
const a = 32;
const b = {
a: 32,
b: "Hello world"
}
const c = [1, 2, 3];
const d = [a,b,c] as const
const draft = <T extends object>(val: T)=> {
const clone = val
Object.defineProperty(clone, brand, {configurable: false, enumerable: false, writable: false, value: true})
return clone as Draft<T>
}
const isDraft = <T extends unknown>(val: T): val is Draft<T> => {
//@ts-ignore
if (val[brand]) {
return true
}
return false
}
const B = draft(b)
const C = draft(c)
const D = draft(d)
console.log("A: ", isDraft(a))
console.log("B: ", isDraft(B))
console.log("C: ", isDraft(C))
console.log("D: ", isDraft(D))
/**
* Accepts a Draft or a Value, but differentiates them on a type level to enforce handling of each of the 2 scenarios
*/
const doSomething = (value: MaybeDraft<number[]>) => {
//const val = current(value) // Error because value could also not be a draft
const val = isDraft(value) ? current(value) : value
return val
}
/**
* Accepts a Draft or a Value, it doesn't care if it might be a Draft and just uses it
*/
const doSomething2 = (value: number[]) => {
return value
}
/**
* Accepts only a Draft, non Drafts are refused on a Type Level at compile time
*/
const current = <T extends object>(value: Draft<T>):T => {
return value
}
doSomething(C)
doSomething2(C)
//const neverHappend = current(c)
const val = current(C)
- Linguagem predominante
- JavaScript
- Estrelas
- 29k
- Forks
- 905
- Merge médio
- 3d 16h
- PRs com merge (30d)
- 22
Preparar o ambiente
Este projeto não oferece contêiner de desenvolvimento, Dockerfile nem guia de contribuição, então a configuração fica por sua conta: comece pelo README e veja nosso guia da primeira contribuição para os passos gerais.
Primeiros passos
- Leia a issue inteira e depois o guia de contribuição do projeto.
- Comente na issue dizendo que vai assumir — evita que duas pessoas façam o mesmo trabalho.
- Faça um fork do repositório e trabalhe em uma branch.
- Abra um pull request que referencie o número da issue.
Mais de immerjs/immer
-
Shrinking an array with `length =` and growing it back loses the patches for the truncated indicesTalvez já em andamento @RClaudiuM assumiu hoje. Aberta
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 75/100
Mantenedores costumam responder em até 4 dias
-
Dificuldade 3/5 1-2 dias Facilidade para iniciantes 35/100
Mantenedores costumam responder em até 4 dias
-
Docs: Chinese (zh-CN) website translation is outdated vs English docsTalvez livre de novo @lijiayou0728 assumiu há 91 dias e não há nenhum pull request aberto. Aberta
Dificuldade 4/5 3-5 dias Facilidade para iniciantes 55/100
immerjs/immer#1242 · 5 comentários ·
Mantenedores costumam responder em até 4 dias
-
Dificuldade 5/5 Mais de uma semana Facilidade para iniciantes 35/100
immerjs/immer#1217 · 1 comentário ·
Mantenedores costumam responder em até 4 dias
-
[Feature Request] Support for "Splice" patches in arrays for CRDT/Y.js integration (and others)Abertaproposal
Dificuldade 5/5 Mais de uma semana Facilidade para iniciantes 25/100
immerjs/immer#1202 · 2 comentários · 1 reação ·
Mantenedores costumam responder em até 4 dias
Todas as issues de immerjs/immer
Issues semelhantes
-
🐛 bug
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 78/100
LibreChat-AI/LibreChat#17887 ·
Mantenedores costumam responder em até 1 dia
-
Step-by-step Ash GuideAberta
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 72/100
liveshowy/webauthn_components#118 ·
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 86/100
showdownjs/showdown#1113 ·
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 82/100
dependents/node-precinct#167 ·
-
Dificuldade 2/5 1-3 horas Facilidade para iniciantes 66/100
volumio/volumio-plugins-sources-bookworm#279 · 1 comentário ·
Mantenedores costumam responder em até 1 dia